
    ~b                         d dl Z d dlZd dlmZ d dlmZmZ d Zd Z G d de	      Z
 G d d	e
      Z G d
 de
      Zd Zd Zy)    N)MethodicalMachine)PythonModule	getModulec                     t        j                  | j                               }|y| }t        |t              s|j
                  }t        |t              s|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.
    F)inspect	getmoduleload
isinstancer   onObjectname__name__)attrsourceModulecurrentModules      3/usr/lib/python3/dist-packages/automat/_discover.pyisOriginalLocationr      sb     $$TYY[1LM5%.. 5 !6!666    c              #   x  K   t        j                  | g      }t               }|r|j                         }|j	                         }t        |t              r&||vr"|j                  |       |j                  |f nt        j                  |      r@t        |      r5||vr1|j                  |       |j                  |j                                nct        |t              rS||vrO|j                  |       |j                  |j                                |j                  |j                                |ryyw)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   values        r   findMachinesViaWrapperr"      s     $ vh'EeG
yy{		e./E4HKK))U""ooe$);D)A7"KKT0023l+W0DKKT0023T--/0 s   D4D:8D:c                       e Zd ZdZy)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                       e Zd ZdZy)NoModulezG
    A prefix of the FQPN was not an importable module or package.
    Nr%   r)   r   r   r,   r,   D   r*   r   r,   c                       e Zd ZdZy)NoObjectz;
    A suffix of the FQPN was not an accessible object
    Nr%   r)   r   r   r.   r.   J   r*   r   r.   c                 L   | st        d      t        j                  | j                  d            }d|v rt        d|       |j	                         	 t              }|r)|j	                         	 |   }|j                          |r)|S # t        $ r t              w xY w# t        $ r |j                         Y nw xY w|}|D ]W  	 t        fd|j                         D              }'# t        $ r& t        dj                  |j                              w xY 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. zMname must be a string giving a '.'-separated list of Python identifiers, not c              3   f   K   | ](  }|j                   j                  d d      d   k(  r| * yw)r0      N)r   rsplit).0child	components     r   	<genexpr>zwrapFQPN.<locals>.<genexpr>y   s8      Lu %

 1 1#q 9" = J # Ls   .1z{}.{})r$   r   r   splitpopleftr   KeyErrorr,   r	   
appendleftnextr   StopIterationr.   formatr   )fqpn
componentsmodule	attributer8   s       @r   wrapFQPNrE   P   sQ    *++""4::c?3J	Z%),- 	- ""$I"9%
 &&(		I&F
 KKM    "y!!"  	!!),	 I F		F L	0H0H0J L LI 	F7>>)..)DEE	F	F s*   B 4B& B#&CC"C11/D c                 *    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"   rE   )rA   s    r   findMachinesrG      s     "(4.11r   )r   r   automatr   twisted.python.modulesr   r   r   r"   	Exceptionr$   r,   r.   rE   rG   r)   r   r   <module>rK      sK      % :7"#1L) { { .b2r   