# Path: wiring/interface.py
# class Interface(object):
#     __doc__ = """
#     A base class for :term:`interface` classes, using the
#     :py:class:`InterfaceMetaclass`.
#     """ + InterfaceMetaclass.__doc__
# 
#     implied = frozenset()
#     """
#     A `frozenset` of this and all base :term:`interfaces <interface>`.
#     """
# 
#     attributes = {}
#     """
#     Dictionary describing provided attributes, including methods. Keys are
#     attribute names and values are :py:class:`Attribute` or :py:class:`Method`
#     instances.
#     """
# 
#     @classmethod
#     def check_compliance(cls, instance):
#         """
#         Checks if given `instance` complies with this :term:`interface`. If
#         `instance` is found to be invalid a :py:exc:`InterfaceComplianceError`
#         subclass is raised.
# 
#         `instance`'s class doesn't have to declare it implements an interface
#         to be validated against it.
# 
#         .. note::
#             Classes cannot be validated against an interface, because instance
#             attributes couldn't be checked.
# 
#         :raises:
#             :py:exc:`MissingAttributeError`,
#             :py:exc:`MethodValidationError`
#         """
#         if inspect.isclass(instance):
#             raise TypeError(
#                 "Only instances, not classes, can be validated against an"
#                 " interface."
#             )
#         for name, value in six.iteritems(cls.attributes):
#             if not hasattr(instance, name):
#                 raise MissingAttributeError(name)
#             if isinstance(value, Method):
#                 value.check_compliance(getattr(instance, name))
# 
# class Method(Attribute):
#     """
#     This class stores a specification of a method, describing its arguments and
#     holding its docstring. It is used by :py:class:`InterfaceMetaclass` to
#     store information about required methods of an :term:`interface`.
#     """
# 
#     def __init__(self, argument_specification, docstring=None):
#         super(Method, self).__init__(docstring)
#         self.argument_specification = argument_specification
#         """
#         An `inspect.ArgSpec` or `inspect.FullArgSpec` (depending on Python
#         version) named tuple specifying arguments taken by described method.
#         These will not include implied `self` argument.
#         """
# 
#     def __repr__(self):
#         return '<Method{}>'.format(
#             inspect.formatargspec(*self.argument_specification)
#         )
# 
#     def check_compliance(self, function):
#         """
#         Checks if a given `function` complies with this specification. If an
#         inconsistency is detected a :py:exc:`MethodValidationError` exception
#         is raised.
# 
#         .. note::
#             This method will not work as expected when `function` is an unbound
#             method (``SomeClass.some_method``), as in Python 3 there is no way
#             to recognize that this is in fact a method. Therefore, the implied
#             `self` argument will not be ignored.
# 
#         :raises:
#             :py:exc:`MethodValidationError`
#         """
#         argument_specification = _get_argument_specification(function)
#         if inspect.ismethod(function):
#             # Remove implied `self` argument from specification if function is
#             # a method.
#             argument_specification = argument_specification._replace(
#                 args=argument_specification.args[1:]
#             )
#         if argument_specification != self.argument_specification:
#             raise MethodValidationError(
#                 function,
#                 self.argument_specification,
#                 argument_specification
#             )
# 
# def get_implemented_interfaces(cls):
#     """
#     Returns a set of :term:`interfaces <interface>` declared as implemented by
#     class `cls`.
#     """
#     if hasattr(cls, '__interfaces__'):
#         return cls.__interfaces__
#     return six.moves.reduce(
#         lambda x, y: x.union(y),
#         map(
#             get_implemented_interfaces,
#             inspect.getmro(cls)[1:]
#         ),
#         set()
#     )


import inspect
from sphinx.domains.python import PyClasslike, PyXRefRole
from sphinx.ext import autodoc
from sphinx.locale import _
from sphinx.util import force_decode
from sphinx.util.docstrings import prepare_docstring
from wiring.interface import Interface, Method, get_implemented_interfaces
                    self.add_line(line, sourcename, i)
                self.add_line(u'', '<autointerface>')
                self.indent = oldindent


def class_interface_documenter(app, what, name, obj, options, lines):
    if what != 'class':
        return
    if options.show_interfaces:
        interfaces = [
            u':py:interface:`{name} <{module}.{name}>`'.format(
                module=interface.__module__,
                name=interface.__name__
            )
            for interface in get_implemented_interfaces(obj)
        ]
        lines.insert(
            0,
            _(u'Implements: {}').format(', '.join(interfaces))
        )
        lines.insert(1, u'')


def method_interface_documenter(app, what, name, obj, options, lines):
    if what != 'method':
        return
    if lines:
        return
    if not getattr(obj, 'im_class'):
        return

# Path: wiring/interface.py
# class Interface(object):
#     __doc__ = """
#     A base class for :term:`interface` classes, using the
#     :py:class:`InterfaceMetaclass`.
#     """ + InterfaceMetaclass.__doc__
# 
#     implied = frozenset()
#     """
#     A `frozenset` of this and all base :term:`interfaces <interface>`.
#     """
# 
#     attributes = {}
#     """
#     Dictionary describing provided attributes, including methods. Keys are
#     attribute names and values are :py:class:`Attribute` or :py:class:`Method`
#     instances.
#     """
# 
#     @classmethod
#     def check_compliance(cls, instance):
#         """
#         Checks if given `instance` complies with this :term:`interface`. If
#         `instance` is found to be invalid a :py:exc:`InterfaceComplianceError`
#         subclass is raised.
# 
#         `instance`'s class doesn't have to declare it implements an interface
#         to be validated against it.
# 
#         .. note::
#             Classes cannot be validated against an interface, because instance
#             attributes couldn't be checked.
# 
#         :raises:
#             :py:exc:`MissingAttributeError`,
#             :py:exc:`MethodValidationError`
#         """
#         if inspect.isclass(instance):
#             raise TypeError(
#                 "Only instances, not classes, can be validated against an"
#                 " interface."
#             )
#         for name, value in six.iteritems(cls.attributes):
#             if not hasattr(instance, name):
#                 raise MissingAttributeError(name)
#             if isinstance(value, Method):
#                 value.check_compliance(getattr(instance, name))
# 
# class Method(Attribute):
#     """
#     This class stores a specification of a method, describing its arguments and
#     holding its docstring. It is used by :py:class:`InterfaceMetaclass` to
#     store information about required methods of an :term:`interface`.
#     """
# 
#     def __init__(self, argument_specification, docstring=None):
#         super(Method, self).__init__(docstring)
#         self.argument_specification = argument_specification
#         """
#         An `inspect.ArgSpec` or `inspect.FullArgSpec` (depending on Python
#         version) named tuple specifying arguments taken by described method.
#         These will not include implied `self` argument.
#         """
# 
#     def __repr__(self):
#         return '<Method{}>'.format(
#             inspect.formatargspec(*self.argument_specification)
#         )
# 
#     def check_compliance(self, function):
#         """
#         Checks if a given `function` complies with this specification. If an
#         inconsistency is detected a :py:exc:`MethodValidationError` exception
#         is raised.
# 
#         .. note::
#             This method will not work as expected when `function` is an unbound
#             method (``SomeClass.some_method``), as in Python 3 there is no way
#             to recognize that this is in fact a method. Therefore, the implied
#             `self` argument will not be ignored.
# 
#         :raises:
#             :py:exc:`MethodValidationError`
#         """
#         argument_specification = _get_argument_specification(function)
#         if inspect.ismethod(function):
#             # Remove implied `self` argument from specification if function is
#             # a method.
#             argument_specification = argument_specification._replace(
#                 args=argument_specification.args[1:]
#             )
#         if argument_specification != self.argument_specification:
#             raise MethodValidationError(
#                 function,
#                 self.argument_specification,
#                 argument_specification
#             )
# 
# def get_implemented_interfaces(cls):
#     """
#     Returns a set of :term:`interfaces <interface>` declared as implemented by
#     class `cls`.
#     """
#     if hasattr(cls, '__interfaces__'):
#         return cls.__interfaces__
#     return six.moves.reduce(
#         lambda x, y: x.union(y),
#         map(
#             get_implemented_interfaces,
#             inspect.getmro(cls)[1:]
#         ),
#         set()
#     )


# Path: sphinx_wiring.py
import inspect
from sphinx.domains.python import PyClasslike, PyXRefRole
from sphinx.ext import autodoc
from sphinx.locale import _
from sphinx.util import force_decode
from sphinx.util.docstrings import prepare_docstring
from wiring.interface import Interface, Method, get_implemented_interfaces

                    self.add_line(line, sourcename, i)
                self.add_line(u'', '<autointerface>')
                self.indent = oldindent


def class_interface_documenter(app, what, name, obj, options, lines):
    if what != 'class':
        return
    if options.show_interfaces:
        interfaces = [
            u':py:interface:`{name} <{module}.{name}>`'.format(
                module=interface.__module__,
                name=interface.__name__
            )
            for interface in get_implemented_interfaces(obj)
        ]
        lines.insert(
            0,
            _(u'Implements: {}').format(', '.join(interfaces))
        )
        lines.insert(1, u'')


def method_interface_documenter(app, what, name, obj, options, lines):
    if what != 'method':
        return
    if lines:
        return
    if not getattr(obj, 'im_class'):
        return

    interfaces = get_implemented_interfaces(obj.im_class)