U
    ˜·0X  ã                   @   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   s<   t  |  ¡ ¡}|dkrdS | }t|tƒs0|j}q|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)ÚinspectZ	getmoduleÚloadÚ
isinstancer   ZonObjectÚnameÚ__name__)ÚattrZsourceModuleZcurrentModule© r   ú3/usr/lib/python3/dist-packages/automat/_discover.pyÚisOriginalLocation   s    
r   c                 c   sÂ   t  | g¡}tƒ }|r¾| ¡ }| ¡ }t|tƒrP||krP| |¡ |j|fV  qt	 
|¡r„t|ƒr„||kr„| |¡ | | ¡ ¡ qt|tƒr||kr| |¡ | | ¡ ¡ | | ¡ ¡ q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   Zisclassr   Ú
extendleftÚiterAttributesr   ZiterModules)ZwithinZqueueZvisitedr
   Úvaluer   r   r   ÚfindMachinesViaWrapper   s"    
ÿ

r   c                   @   s   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   >   s   r   c                   @   s   e Zd ZdZdS )ÚNoModulezG
    A prefix of the FQPN was not an importable module or package.
    Nr   r   r   r   r   r   D   s   r   c                   @   s   e Zd ZdZdS )ÚNoObjectz;
    A suffix of the FQPN was not an accessible object
    Nr   r   r   r   r   r   J   s   r   c              	      s  | st dƒ‚t |  d¡¡}d|kr2t d| f ƒ‚| ¡ ‰ ztˆ ƒ}W n tk
rb   tˆ ƒ‚Y nX |rª| ¡ ‰ z|ˆ  }W n" tk
rž   | ˆ ¡ Y q®Y qdX | 	¡  qd|S |}|D ]J‰ zt
‡ fdd„| ¡ D ƒƒ}W q¶ tk
rþ   td |jˆ ¡ƒ‚Y q¶X q¶|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)Ú.0Zchild©Z	componentr   r   Ú	<genexpr>y   s    ÿzwrapFQPN.<locals>.<genexpr>z{}.{})r   r   r   ÚsplitÚpopleftr   ÚKeyErrorr   Ú
appendleftr   Únextr   ÚStopIterationr   Úformatr   )ÚfqpnZ
componentsÚmoduleZ	attributer   r$   r   ÚwrapFQPNP   s<    ÿÿ


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    r0   )r   r   Zautomatr   Ztwisted.python.modulesr   r   r   r   Ú	Exceptionr   r   r   r/   r0   r   r   r   r   Ú<module>   s   &1