U
    j5{i”)  ã                   @   s„   d dl Z d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlm	Z	 g Z
G dd	„ d	ƒZG d
d„ deƒZdd„ Zeƒ ZdS )é    N)ÚFunctionType)Ú	Interface)ÚclassImplements)ÚInterfaceClass)Ú_decorator_non_return)ÚfromFunctionc                   @   s   e Zd Zdd„ ZdS )Úoptionalc                 C   s   |j | _ d S ©N©Ú__doc__)ÚselfÚmethod© r   úB/tmp/pip-unpacked-wheel-jkvlexts/zope/interface/common/__init__.pyÚ__init__$   s    zoptional.__init__N)Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r   r       s   r   c                   @   sf   e Zd ZdZdd„ Zedd„ ƒZdd„ Zedd	„ ƒZed
d„ ƒZ	dd„ Z
ddd„Zdd„ Zdd„ ZdS )ÚABCInterfaceClassaü
  
    An interface that is automatically derived from a
    :class:`abc.ABCMeta` type.

    Internal use only.

    The body of the interface definition *must* define
    a property ``abc`` that is the ABC to base the interface on.

    If ``abc`` is *not* in the interface definition, a regular
    interface will be defined instead (but ``extra_classes`` is still
    respected).

    Use the ``@optional`` decorator on method definitions if
    the ABC defines methods that are not actually required in all cases
    because the Python language has multiple ways to implement a protocol.
    For example, the ``iter()`` protocol can be implemented with
    ``__iter__`` or the pair ``__len__`` and ``__getitem__``.

    When created, any existing classes that are registered to conform
    to the ABC are declared to implement this interface. This is *not*
    automatically updated as the ABC registry changes. If the body of the
    interface definition defines ``extra_classes``, it should be a
    tuple giving additional classes to declare implement the interface.

    Note that this is not fully symmetric. For example, it is usually
    the case that a subclass relationship carries the interface
    declarations over::

        >>> from zope.interface import Interface
        >>> class I1(Interface):
        ...     pass
        ...
        >>> from zope.interface import implementer
        >>> @implementer(I1)
        ... class Root(object):
        ...     pass
        ...
        >>> class Child(Root):
        ...     pass
        ...
        >>> child = Child()
        >>> isinstance(child, Root)
        True
        >>> from zope.interface import providedBy
        >>> list(providedBy(child))
        [<InterfaceClass __main__.I1>]

    However, that's not the case with ABCs and ABC interfaces. Just
    because ``isinstance(A(), AnABC)`` and ``isinstance(B(), AnABC)``
    are both true, that doesn't mean there's any class hierarchy
    relationship between ``A`` and ``B``, or between either of them
    and ``AnABC``. Thus, if ``AnABC`` implemented ``IAnABC``, it would
    not follow that either ``A`` or ``B`` implements ``IAnABC`` (nor
    their instances provide it)::

        >>> class SizedClass(object):
        ...     def __len__(self): return 1
        ...
        >>> from collections.abc import Sized
        >>> isinstance(SizedClass(), Sized)
        True
        >>> from zope.interface import classImplements
        >>> classImplements(Sized, I1)
        None
        >>> list(providedBy(SizedClass()))
        []

    Thus, to avoid conflicting assumptions, ABCs should not be
    declared to implement their parallel ABC interface. Only concrete
    classes specifically registered with the ABC should be declared to
    do so.

    .. versionadded:: 5.0.0
    c                    sÞ   |ˆ _ | dd¡}| dd¡}d|krNt ˆ |||¡ t ˆ ||¡ tˆ _d S | d¡}|ˆ _t|ƒˆ _	t|ƒˆ _
|dd … |j ks�t||fƒ‚‡ fdd„t|ƒ ¡ D ƒ}ˆ  |¡|d< | |¡ t ˆ |||¡ ˆ  ¡  d S )	NÚextra_classesr   Úignored_classesÚabcé   c                    s<   i | ]4\}}t |tƒrˆ  |¡sˆ  |¡s|ˆ  ||¡“qS r   )Ú
isinstancer   Ú#_ABCInterfaceClass__is_private_nameÚ,_ABCInterfaceClass__is_reverse_protocol_nameÚ(_ABCInterfaceClass__method_from_function©Ú.0ÚkÚv©r   r   r   Ú
<dictcomp>�   s   


ü z.ABCInterfaceClass.__init__.<locals>.<dictcomp>r   )r   Úpopr   r   r   Ú$_ABCInterfaceClass__register_classesÚ	__class__Ú_ABCInterfaceClass__abcÚtupleÚ!_ABCInterfaceClass__extra_classesÚ#_ABCInterfaceClass__ignored_classesÚAssertionErrorÚvarsÚitemsÚ$_ABCInterfaceClass__create_class_docÚupdate)r   ÚnameÚbasesÚattrsr   r   Úbased_onÚmethodsr   r!   r   r   z   s0      ÿ




ü

zABCInterfaceClass.__init__c                 C   sL   dd„ |   ¡ D ƒ}|D ]}t| |< q|s,dS dd dd„ |  ¡ D ƒ¡ }|S )Nc                 S   s    i | ]\}}t |tƒr||“qS r   )r   r   r   r   r   r   r"   ¢   s     
  z@ABCInterfaceClass.__optional_methods_to_docs.<locals>.<dictcomp>Ú z)

The following methods are optional:
 - z
-c                 s   s"   | ]\}}|› d |j › �V  qdS )Ú
Nr
   r   r   r   r   Ú	<genexpr>©   s    z?ABCInterfaceClass.__optional_methods_to_docs.<locals>.<genexpr>)r,   r   Újoin)r1   Ú	optionalsr   Zdocsr   r   r   Z__optional_methods_to_docs    s    
ÿ
z,ABCInterfaceClass.__optional_methods_to_docsc                    sˆ   | j }dd„ ‰ d ‡ fdd„t|  ¡ ˆ d�D ƒ¡}|r>d| }|jpFd}| ¡ }|r\|d	 nd}d
 |j|j| 	d|¡|  
|¡|¡}|S )Nc                 S   s<   | j }| j}|tj krd| S |dkr*d}d|› d|› d�S )Nz`%s`Ú_ioÚioú`Ú.)r   r   Ústr)ÚcÚmodr/   r   r   r   Úref±   s    
z1ABCInterfaceClass.__create_class_doc.<locals>.refz
 - c                 3   s   | ]}ˆ |ƒV  qd S r	   r   )r   r>   ©r@   r   r   r6   º   s   ÿz7ABCInterfaceClass.__create_class_doc.<locals>.<genexpr>)Úkeyz!

Known implementations are:

 - r4   r   z&Interface for the ABC `{}.{}`.

{}{}{}r   )r&   r7   ÚsortedÚgetRegisteredConformersr   Ú
splitlinesÚformatr   r   ÚgetÚ,_ABCInterfaceClass__optional_methods_to_docs)r   r1   r2   Zimplementations_docZbased_on_docÚdocr   rA   r   Z__create_class_doc®   s&    	þÿ
 
üz$ABCInterfaceClass.__create_class_docc                 C   s"   |   d¡r|  d¡rdS |   d¡S )NÚ__FÚ_©Ú
startswithÚendswith©r/   r   r   r   Z__is_private_nameÏ   s    z#ABCInterfaceClass.__is_private_namec                 C   s   |   d¡o|  d¡S )NZ__rrJ   rL   rO   r   r   r   Z__is_reverse_protocol_nameÕ   s    z,ABCInterfaceClass.__is_reverse_protocol_namec                 C   s"   t || |d�}|jdd … |_|S )NrO   r   )r   Ú
positional)r   Úfunctionr/   r   r   r   r   Z__method_from_functionÝ   s    z(ABCInterfaceClass.__method_from_functionNc                 C   sH   |d k	r|n|   ¡ }|d k	r |n| j}|D ]}||kr8q*t|| ƒ q*d S r	   )rD   r)   r   )r   Z
conformersr   ZignoredÚclsr   r   r   Z__register_classesä   s    þþz$ABCInterfaceClass.__register_classesc                 C   s   | j S )z;
        Return the ABC this interface represents.
        )r&   r!   r   r   r   ÚgetABCô   s    zABCInterfaceClass.getABCc                 C   sŽ   | j }zt|jƒt|jƒ }W n\ tk
rz   ddlm} ||ƒ}|d }|d }dd„ t ||¡D ƒ}dd„ |D ƒ}Y nX t	t || j
¡ƒS )zz
        Return an iterable of the classes that are known to conform to
        the ABC this interface parallels.
        r   )Ú	_get_dumpr   c                 S   s   g | ]
}|ƒ ‘qS r   r   ©r   Úxr   r   r   Ú
<listcomp>  s     z=ABCInterfaceClass.getRegisteredConformers.<locals>.<listcomp>c                 S   s   g | ]}|d k	r|‘qS r	   r   rU   r   r   r   rW     s      )r&   ÚlistÚ_abc_registryÚ
_abc_cacheÚAttributeErrorr   rT   Ú	itertoolsÚchainÚsetr(   )r   r2   Z
registeredrT   ÚdataÚregistryÚcacher   r   r   rD   ú   s    ÿz)ABCInterfaceClass.getRegisteredConformers)NN)r   r   r   r   r   ÚstaticmethodrH   r-   r   r   r   r$   rS   rD   r   r   r   r   r   (   s   Q&
!


r   c                  C   s0   dt fi f} tjtf| žŽ }tj|f| žŽ  |S )NÚABCInterface)r   r   Ú__new__r   r   )Zabc_name_bases_attrsÚinstancer   r   r   Ú_create_ABCInterface  s    ÿÿrf   )r\   Útypesr   Zzope.interfacer   r   Zzope.interface.interfacer   r   r   Ú__all__r   r   rf   rc   r   r   r   r   Ú<module>   s   	 o