o
    q+WZ  ã                   @   s€   d dl Z d dlZd dlmZ d dlmZmZ dd„ Zdd„ ZG dd	„ d	e	ƒZ
G d
d„ de
ƒZG dd„ de
ƒZdd„ Zdd„ ZdS )é    N)ÚMethodicalMachine)ÚPythonModuleÚ	getModulec                 C   sD   t  |  ¡ ¡}|du rdS | }t|tƒs|j}t|tƒr|j|jkS )z•
    Attempt to discover if this appearance of a PythonAttribute
    representing a class refers to the module where that class was
    defined.
    NF)ÚinspectÚ	getmoduleÚloadÚ
isinstancer   ÚonObjectÚnameÚ__name__)ÚattrÚsourceModuleÚcurrentModule© r   ú3/usr/lib/python3/dist-packages/automat/_discover.pyÚisOriginalLocation   s   

ÿr   c                 c   sÊ   � t  | g¡}tƒ }|rc| ¡ }| ¡ }t|tƒr)||vr)| |¡ |j|fV  n6t	 
|¡rCt|ƒrC||vrC| |¡ | | ¡ ¡ nt|tƒr_||vr_| |¡ | | ¡ ¡ | | ¡ ¡ |sdS dS )aÁ  
    Recursively yield L{MethodicalMachine}s and their FQPNs within a
    L{PythonModule} or a L{twisted.python.modules.PythonAttribute}
    wrapper object.

    Note that L{PythonModule}s may refer to packages, as well.

    The discovery heuristic considers L{MethodicalMachine} instances
    that are module-level attributes or class-level attributes
    accessible from module scope.  Machines inside nested classes will
    be discovered, but those returned from functions or methods will not be.

    @type within: L{PythonModule} or L{twisted.python.modules.PythonAttribute}
    @param within: Where to start the search.

    @return: a generator which yields FQPN, L{MethodicalMachine} pairs.
    N)ÚcollectionsÚdequeÚsetÚpopr   r   r   Úaddr
   r   Úisclassr   Ú
extendleftÚiterAttributesr   ÚiterModules)ÚwithinÚqueueÚvisitedr   Úvaluer   r   r   ÚfindMachinesViaWrapper   s$   €


òr   c                   @   ó   e Zd ZdZdS )ÚInvalidFQPNzH
    The given FQPN was not a dot-separated list of Python objects.
    N©r   Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r!   >   ó    r!   c                   @   r    )ÚNoModulezG
    A prefix of the FQPN was not an importable module or package.
    Nr"   r   r   r   r   r'   D   r&   r'   c                   @   r    )ÚNoObjectz;
    A suffix of the FQPN was not an accessible object
    Nr"   r   r   r   r   r(   J   r&   r(   c              	      sô   | st dƒ‚t |  d¡¡}d|v rt d| f ƒ‚| ¡ ‰ ztˆ ƒ}W n ty.   tˆ ƒ‚w |rP| ¡ ‰ z|ˆ  }W n tyI   | ˆ ¡ Y n	w | 	¡  |s1|S |}|D ]!‰ zt
‡ fdd„| ¡ D ƒƒ}W qV tyw   td |jˆ ¡ƒ‚w |S )z®
    Given an FQPN, retrieve the object via the global Python module
    namespace and wrap it with a L{PythonModule} or a
    L{twisted.python.modules.PythonAttribute}.
    zFQPN was emptyÚ.Ú zOname must be a string giving a '.'-separated list of Python identifiers, not %rc                 3   s*   � | ]}|j  d d¡d ˆ kr|V  qdS )r)   é   éÿÿÿÿN)r
   Úrsplit)Ú.0Úchild©Ú	componentr   r   Ú	<genexpr>y   s   € ÿÿzwrapFQPN.<locals>.<genexpr>z{}.{})r!   r   r   ÚsplitÚpopleftr   ÚKeyErrorr'   Ú
appendleftr   Únextr   ÚStopIterationr(   Úformatr
   )ÚfqpnÚ
componentsÚmoduleÚ	attributer   r0   r   ÚwrapFQPNP   sD   ÿÿÿ
þø
ÿr>   c                 C   s   t t| ƒƒS )a'  
    Recursively yield L{MethodicalMachine}s and their FQPNs in and
    under the a Python object specified by an FQPN.

    The discovery heuristic considers L{MethodicalMachine} instances
    that are module-level attributes or class-level attributes
    accessible from module scope.  Machines inside nested classes will
    be discovered, but those returned from functions or methods will not be.

    @type within: an FQPN
    @param within: Where to start the search.

    @return: a generator which yields FQPN, L{MethodicalMachine} pairs.
    )r   r>   )r:   r   r   r   ÚfindMachines�   s   r?   )r   r   Úautomatr   Útwisted.python.modulesr   r   r   r   Ú	Exceptionr!   r'   r(   r>   r?   r   r   r   r   Ú<module>   s    &1