o
    Ñó·iM  ã                   @  s¼   d dl mZ d dlZd dlZd dlmZmZ d dlmZm	Z	m
Z
 d dlmZ ddlmZmZmZ ddd„Zd dd„ZG dd„ deƒZG dd„ deƒZG dd„ deƒZd!dd„Zd"dd„ZdS )#é    )ÚannotationsN)ÚAnyÚIterator)ÚPythonAttributeÚPythonModuleÚ	getModule)ÚMethodicalMachineé   )ÚTypeMachineÚInputProtocolÚCoreÚattrúPythonAttribute | PythonModuleÚreturnÚboolc                 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   ZonObjectÚnameÚ__name__)r   ZsourceModuleZcurrentModule© r   úWC:\Users\psant\Downloads\PAF backend\school\venv\Lib\site-packages\automat/_discover.pyÚisOriginalLocation   s   

ÿr   ÚwithinúPythonModule | PythonAttributeúJIterator[tuple[str, MethodicalMachine | TypeMachine[InputProtocol, Core]]]c                 c  sÔ   � t  | g¡}tƒ }|rh| ¡ }| ¡ }t|tƒst|tƒr.||vr.| |¡ |j	|fV  n6t
 |¡rHt|ƒrH||vrH| |¡ | | ¡ ¡ nt|tƒrd||vrd| |¡ | | ¡ ¡ | | ¡ ¡ |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   r
   Úaddr   r   Úisclassr   Ú
extendleftÚiterAttributesr   ZiterModules)r   ÚqueueÚvisitedr   Úvaluer   r   r   ÚfindMachinesViaWrapper   s8   €úÿÿþ
ÿÿÿ

ð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*   O   ó    r*   c                   @  r)   )ÚNoModulezG
    A prefix of the FQPN was not an importable module or package.
    Nr+   r   r   r   r   r0   U   r/   r0   c                   @  r)   )ÚNoObjectz;
    A suffix of the FQPN was not an accessible object
    Nr+   r   r   r   r   r1   [   r/   r1   ÚfqpnÚstrc              	     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 qRw | 	¡  |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 )r4   r	   éÿÿÿÿN)r   Úrsplit)Ú.0Úchild©Ú	componentr   r   Ú	<genexpr>‹   s   € ý
ÿzwrapFQPN.<locals>.<genexpr>z{}.{}N)r*   r   r   ÚsplitÚpopleftr   ÚKeyErrorr0   Ú
appendleftr   Únextr$   ÚStopIterationr1   Úformatr   )r2   Ú
componentsÚmoduleÚ	attributer   r:   r   ÚwrapFQPNa   sH   ÿÿÿ
þø
þÿrG   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.

    @param fqpn: a fully-qualified Python identifier (i.e. the dotted
        identifier of an object defined at module or class scope, including the
        package and modele names); where to start the search.

    @return: a generator which yields (C{FQPN}, L{MethodicalMachine}) pairs.
    N)r(   rG   )r2   r   r   r   ÚfindMachines–   s   rH   )r   r   r   r   )r   r   r   r   )r2   r3   r   r   )r2   r3   r   r   )Ú
__future__r   r   r   Útypingr   r   Ztwisted.python.modulesr   r   r   Zautomatr   Z_typedr
   r   r   r   r(   Ú	Exceptionr*   r0   r1   rG   rH   r   r   r   r   Ú<module>   s    

0
5