o
    Ñó·i;D  ã                   @  sÈ  U 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 d dl	m
Z d dlmZ d dlmZmZmZmZmZ ejdk rCd d	lmZ nd d	lmZ d
dlmZmZmZmZ d
dlmZ e dg d¢¡Zdd„ Z dd„ Z!dd„ Z"edd�G dd„ de#ƒƒZ$dDd!d"„Z%d#d$„ Z&d%d&„ Z'dEd*d+„Z(d,d-„ Z)ed.ƒZ*ed/ƒZ+ed0d1�G d2d3„ d3e#ƒƒZ,edd�G d4d5„ d5e#ƒƒZ-ee.gdf Z/d6Z0d7e1d8< dFd<d=„Z2ed0d1�G d>d?„ d?e#ƒƒZ3eƒ Z4d@dA„ Z5G dBdC„ dCe#ƒZ6dS )Gé    )ÚannotationsN)Ú	dataclassÚfield©Úwraps)Úgetfullargspec)Úcount)ÚAnyÚCallableÚHashableÚIterableÚTypeVar)é   é
   )Ú	TypeAliasé   )Ú	AutomatonÚOutputTracerÚTracerÚTransitioner)ÚpreserveNameÚArgSpec©ÚargsÚvarargsÚvarkwÚdefaultsÚ
kwonlyargsÚkwonlydefaultsr   c              
   C  sX   t | ƒ}tt|jƒ|j|j|jr|jndt|jƒ|jr"t|j 	¡ ƒndt|j
 	¡ ƒd�S )zÑ
    Normalize inspect.ArgSpec across python versions
    and convert mutable attributes to immutable types.

    :param Callable func: A function.
    :return: The function's ArgSpec.
    :rtype: ArgSpec
    © r   N)ÚgetArgsSpecr   Útupler   r   r   r   r   r   Úitemsr   )ÚfuncÚspecr   r   úYC:\Users\psant\Downloads\PAF backend\school\venv\Lib\site-packages\automat/_methodical.pyÚ_getArgSpec"   s   	÷r&   c                 C  s@   t | j| j | jrdnd | jrdnd tdd„ | jD ƒƒ ƒS )aê  
    Get the name of all arguments defined in a function signature.

    The name of * and ** arguments is normalized to "*args" and "**kwargs".

    Return type annotations are omitted, since we don't constrain input methods
    to have the same return type as output methods, nor output methods to have
    the same output type.

    :param ArgSpec spec: A function to interrogate for a signature.
    :return: The set of all argument names in `func`s signature.
    :rtype: Set[str]
    )z*argsr   )z**kwargsc                 s  s    � | ]}|d  dkr|V  qdS )r   ÚreturnNr   )Ú.0Úar   r   r%   Ú	<genexpr>L   s   € z_getArgNames.<locals>.<genexpr>N)Úsetr   r   r   r   r!   r   )r$   r   r   r%   Ú_getArgNames9   s   ÿþýüÿr,   c                   s   t ˆ ƒ‡ fdd„ƒ}|S )a  
    Decorate a function so all its arguments must be passed by keyword.

    A useful utility for decorators that take arguments so that they don't
    accidentally get passed the thing they're decorating as their first
    argument.

    Only works for methods right now.
    c                   s   ˆ | fi |¤ŽS ©Nr   )ÚselfÚkw©Úfr   r%   Úg[   s   z_keywords_only.<locals>.gNr   )r1   r2   r   r0   r%   Ú_keywords_onlyP   s   r3   T)Úfrozenc                   @  s`   e Zd ZU dZedd�Zded< eƒ Zded< edd�Zded	< d
d
e	fddd„Z
ddd„Zd
S )ÚMethodicalStatez-
    A state for a L{MethodicalMachine}.
    F©ÚreprÚMethodicalMachineÚmachineúCallable[..., Any]ÚmethodÚboolÚ
serializedNÚinputÚMethodicalInputÚenterúMethodicalState | NoneÚoutputsú!Iterable[MethodicalOutput] | NoneÚ	collectorúCallable[[Iterable[T]], object]r'   ÚNonec                 C  s‚   |du r| }|du rg }t |jƒ}|D ]!}t |jƒ}| |¡s4tdj|jj|jjt|jƒt|jƒd�ƒ‚q| j 	| ||||¡ dS )aÿ  
        Declare a state transition within the L{MethodicalMachine} associated
        with this L{MethodicalState}: upon the receipt of the `input`, enter
        the `state`, emitting each output in `outputs`.

        @param input: The input triggering a state transition.

        @param enter: The resulting state.

        @param outputs: The outputs to be triggered as a result of the declared
            state transition.

        @param collector: The function to be used when collecting output return
            values.

        @raises TypeError: if any of the `outputs` signatures do not match the
            `inputs` signature.

        @raises ValueError: if the state transition from `self` via `input` has
            already been defined.
        Nzdmethod {input} signature {inputSignature} does not match output {output} signature {outputSignature})r>   ÚoutputZinputSignatureZoutputSignature)
r,   ÚargSpecÚissubsetÚ	TypeErrorÚformatr;   Ú__name__r    r9   Ú_oneTransition)r.   r>   r@   rB   rD   Z	inputArgsrG   Z
outputArgsr   r   r%   Úuponl   s&   


úÿÿzMethodicalState.uponÚstrc                 C  ó   | j jS r-   ©r;   rL   ©r.   r   r   r%   Ú_nameœ   ó   zMethodicalState._name)
r>   r?   r@   rA   rB   rC   rD   rE   r'   rF   ©r'   rO   )rL   Ú
__module__Ú__qualname__Ú__doc__r   r9   Ú__annotations__r;   r=   ÚlistrN   rS   r   r   r   r%   r5   b   s   
 û0r5   ÚoselfÚobjectÚsymbolrO   Ú	automatonú=Automaton[MethodicalState, MethodicalInput, MethodicalOutput]r'   ú@Transitioner[MethodicalState, MethodicalInput, MethodicalOutput]c                 C  s0   t | |dƒ}|du rt||jƒ}t| ||ƒ |S )z
    Get a L{Transitioner}
    N)Úgetattrr   ÚinitialStateÚsetattr)r[   r]   r^   Útransitionerr   r   r%   Ú_transitionerFromInstance    s   þre   c                   C  s   d S r-   r   r   r   r   r%   Ú_empty²   s   rf   c                   C  s   dS )Ú	docstringNr   r   r   r   r%   Ú
_docstring¶   s    rh   r1   r:   rF   c                 C  s$   | j jtj jtj jfvrtdƒ‚d S )Nzfunction body must be empty)Ú__code__Úco_coderf   rh   Ú
ValueErrorr0   r   r   r%   ÚassertNoCodeº   s   ÿrl   c                   sÚ   t t|jdd… | ƒƒ}ˆjr| }n	‡fdd„|D ƒ}t |ƒ‰|D ]
\}}ˆ||f7 ‰q!t|jddd… |jddd… ƒ}‡fdd„|D ƒ}	|	 |¡ ˆjrT|	}
||
fS ˆjdd… ˆj ‰ ‡ fdd„|	 ¡ D ƒ}
||
fS )	a†  
    Filter out arguments that were passed to input that output won't accept.

    :param tuple args: The *args that input received.
    :param dict kwargs: The **kwargs that input received.
    :param ArgSpec inputSpec: The input's arg spec.
    :param ArgSpec outputSpec: The output's arg spec.
    :return: The args and kwargs that output will accept.
    :rtype: Tuple[tuple, dict]
    r   Nc                   s   g | ]\}}|ˆ j v r|‘qS r   )r   ©r(   ÚnÚv)Ú
outputSpecr   r%   Ú
<listcomp>Ü   ó    z_filterArgs.<locals>.<listcomp>éÿÿÿÿc                   s   i | ]\}}|ˆ vr||“qS r   r   rm   )Úpassed_arg_namesr   r%   Ú
<dictcomp>ã   rr   z_filterArgs.<locals>.<dictcomp>c                   s   i | ]\}}|ˆ v r||“qS r   r   rm   )Úall_accepted_namesr   r%   ru   ì   s
    ÿÿ)	r!   Úzipr   r   r   Úupdater   r   r"   )r   ÚkwargsZ	inputSpecrp   Z
named_argsZreturn_argsÚnameÚvaluer   Zfull_kwargsZreturn_kwargsr   )rv   rp   rt   r%   Ú_filterArgsÊ   s$   "
û
ÿr|   ÚTÚRF)Úeqc                   @  sŒ   e Zd ZU dZedd�Zded< eƒ Zded< edd�Zded	< ee	dd
�Z
ded< eddd�Zded< ddd„Zdddd„Zddd„ZdS ) r?   z.
    An input for a L{MethodicalMachine}.
    Fr6   r_   r^   r:   r;   rO   r]   )Údefault_factoryr7   z1dict[MethodicalState, Callable[[Iterable[T]], R]]Ú
collectors)Úinitr7   r   rH   r'   rF   c                 C  s   t | jƒ| _t| jƒ d S r-   )r&   r;   rH   rl   rR   r   r   r%   Ú__post_init__  s   zMethodicalInput.__post_init__Nr[   r\   Útypec                   s:   t ˆ ˆjˆjƒ‰tˆjƒtˆjƒd‡ ‡‡fdd„ƒƒ}|S )	zÁ
        Return a function that takes no arguments and returns values returned
        by output functions produced by the given L{MethodicalInput} in
        C{oself}'s current state.
        r   r\   ry   r'   c                    s’   ˆj ˆ g| ¢R i |¤Ž ˆj}ˆ ˆ¡\}}ˆj| }g }|D ]%}|d ur)||ƒ t| |ˆj|jƒ\}}	|ˆ g|¢R i |	¤Ž}
| |
¡ q||ƒS r-   )r;   Ú_stateZ
transitionr�   r|   rH   Úappend)r   ry   ZpreviousStaterB   Z	outTracerrD   ÚvaluesrG   r)   Úkr{   ©r[   r.   rd   r   r%   ÚdoInput  s   
z(MethodicalInput.__get__.<locals>.doInputN)r   r\   ry   r\   r'   r\   )re   r]   r^   r   r;   r   )r.   r[   r„   rŠ   r   r‰   r%   Ú__get__  s
   zMethodicalInput.__get__c                 C  rP   r-   rQ   rR   r   r   r%   rS   &  rT   zMethodicalInput._name©r'   rF   r-   )r[   r\   r„   rF   r'   r\   rU   )rL   rV   rW   rX   r   r^   rY   r;   r]   Údictr�   rH   rƒ   r‹   rS   r   r   r   r%   r?   ÷   s   
 ÿÿ
r?   c                   @  sh   e Zd ZU dZedd�Zded< ded< edddd�Zd	ed
< ddd„Zddd„Z	dd„ Z
ddd„ZdS )ÚMethodicalOutputz/
    An output for a L{MethodicalMachine}.
    Fr6   r8   r9   r:   r;   )r‚   r7   Úcomparer   rH   r'   rF   c                 C  s   t | jƒ| jd< d S )NrH   )r&   r;   Ú__dict__rR   r   r   r%   rƒ   4  s   zMethodicalOutput.__post_init__Nc                 C  s   t dj|j| jjd�ƒ‚)zX
        Outputs are private, so raise an exception when we attempt to get one.
        zf{cls}.{method} is a state-machine output method; to produce this output, call an input method instead.)Úclsr;   N)ÚAttributeErrorrK   rL   r;   ©r.   r[   r„   r   r   r%   r‹   7  s   
þÿzMethodicalOutput.__get__c                 O  s   | j |g|¢R i |¤ŽS )z-
        Call the underlying method.
        N)r;   )r.   r[   r   ry   r   r   r%   Ú__call__B  s   zMethodicalOutput.__call__rO   c                 C  rP   r-   rQ   rR   r   r   r%   rS   H  rT   zMethodicalOutput._namerŒ   r-   rU   )rL   rV   rW   rX   r   r9   rY   rH   rƒ   r‹   r”   rS   r   r   r   r%   rŽ   *  s   
 

rŽ   z4Callable[[str, str, str], StringOutputTracer | None]r   ÚStringTracerÚwrappedúStringTracer | NoneúATracer[MethodicalState, MethodicalInput, MethodicalOutput] | Nonec                   s   ˆ d u rd S d
‡ fdd	„}|S )NÚstater5   r>   r?   rG   r'   ú%OutputTracer[MethodicalOutput] | Nonec                   s0   ˆ|   ¡ |  ¡ |  ¡ ƒ‰ ˆ d ur‡ fdd„S d S )Nc                   s   ˆ |   ¡ ƒS r-   ©rS   )Úout©Úresultr   r%   Ú<lambda>]  s    z,wrapTracer.<locals>.tracer.<locals>.<lambda>r›   )r™   r>   rG   ©r–   r�   r%   ÚtracerV  s   zwrapTracer.<locals>.tracer)r™   r5   r>   r?   rG   r5   r'   rš   r   )r–   r¡   r   r    r%   Ú
wrapTracerP  s   
r¢   c                   @  s@   e Zd ZU edd�Zded< edd�Zded< 	dddd„ZdS )ÚMethodicalTracerFr6   r_   r^   rO   r]   Nr[   r\   r„   r'   úCallable[[StringTracer], None]c                   s"   t || j| jƒ‰ d‡ fdd„}|S )Nr¡   r—   r'   rF   c                   s   ˆ   t| ƒ¡ d S r-   )ÚsetTracer¢   )r¡   ©rd   r   r%   r¥   o  s   z*MethodicalTracer.__get__.<locals>.setTrace)r¡   r—   r'   rF   )re   r]   r^   )r.   r[   r„   r¥   r   r¦   r%   r‹   j  s   zMethodicalTracer.__get__r-   )r[   r\   r„   r\   r'   r¤   )rL   rV   rW   r   r^   rY   r]   r‹   r   r   r   r%   r£   c  s   
 ÿÿr£   c                   C  s   dt ttƒƒ S )z,
    Create a unique Python identifier.
    Z_symbol_N)rO   ÚnextÚcounterr   r   r   r%   Úgensymx  s   r©   c                   @  s‚   e Zd ZdZdd„ Zddd„Ze	d d!dd„ƒZedd„ ƒZedd„ ƒZ	dd„ Z
edd„ ƒZedd„ ƒZed"dd„ƒZdd„ ZdS )#r8   ze
    A L{MethodicalMachine} is an interface to an L{Automaton} that uses methods
    on a class.
    c                 C  s   t ƒ | _i | _tƒ | _d S r-   )r   Ú
_automatonZ	_reducersr©   Ú_symbolrR   r   r   r%   Ú__init__…  s   zMethodicalMachine.__init__Nc                 C  s   |durt dƒ‚| S )z°
        L{MethodicalMachine} is an implementation detail for setting up
        class-level state; applications should never need to access it on an
        instance.
        Nz.MethodicalMachine is an implementation detail.)r’   r“   r   r   r%   r‹   Š  s   zMethodicalMachine.__get__FÚinitialr<   Úterminalr=   r   c                   s   ‡ ‡‡fdd„}|S )aí  
        Declare a state, possibly an initial state or a terminal state.

        This is a decorator for methods, but it will modify the method so as
        not to be callable any more.

        @param initial: is this state the initial state?  Only one state on
            this L{automat.MethodicalMachine} may be an initial state; more
            than one is an error.

        @param terminal: Is this state a terminal state?  i.e. a state that the
            machine can end up in?  (This is purely informational at this
            point.)

        @param serialized: a serializable value to be used to represent this
            state to external systems.  This value should be hashable; L{str}
            is a good type to use.
        c                   s   t ˆ| ˆd�}ˆ r|ˆj_|S )N)r9   r;   r=   )r5   rª   rb   )ZstateMethodr™   ©r­   r.   r=   r   r%   Ú	decorator«  s   ÿz*MethodicalMachine.state.<locals>.decoratorNr   )r.   r­   r®   r=   r°   r   r¯   r%   r™   ”  s   zMethodicalMachine.statec                   ó   ‡ fdd„}|S )zM
        Declare an input.

        This is a decorator for methods.
        c                   s   t ˆ j| ˆ jd�S )N)r^   r;   r]   )r?   rª   r«   )ZinputMethodrR   r   r%   r°   ½  s   
ÿz*MethodicalMachine.input.<locals>.decoratorNr   ©r.   r°   r   rR   r%   r>   µ  s   zMethodicalMachine.inputc                   r±   )zÚ
        Declare an output.

        This is a decorator for methods.

        This method will be called when the state machine transitions to this
        state as specified in the decorated `output` method.
        c                   s   t ˆ | d�S )N)r9   r;   )rŽ   )ZoutputMethodrR   r   r%   r°   Ï  s   z+MethodicalMachine.output.<locals>.decoratorNr   r²   r   rR   r%   rG   Ä  s   zMethodicalMachine.outputc                 C  s$   | j  |||t|ƒ¡ ||j|< dS )z.
        See L{MethodicalState.upon}.
        N)rª   ZaddTransitionr!   r�   )r.   Z
startStateZ
inputTokenZendStateZoutputTokensrD   r   r   r%   rM   Ô  s   ÿz MethodicalMachine._oneTransitionc                   r±   )ú c                   ó   t ˆ ƒ‡ ‡fdd„ƒ}|S )Nc                   s   t | ˆjˆjƒ}ˆ | |jjƒS r-   )re   r«   rª   r…   r=   )r[   rd   ©Ú	decorateer.   r   r%   Ú	serializeð  s   
ÿzBMethodicalMachine.serializer.<locals>.decorator.<locals>.serializer   )r¶   r·   rR   ©r¶   r%   r°   ï  s   z/MethodicalMachine.serializer.<locals>.decoratorNr   r²   r   rR   r%   Ú
serializerë  s   
zMethodicalMachine.serializerc                   r±   )r³   c                   r´   )Nc                   sR   ˆ | g|¢R i |¤Ž}i }ˆj  ¡ D ]}|||j< qt| ˆjˆj ƒ}|| |_d S r-   )rª   Zstatesr=   re   r«   r…   )r[   r   ry   r™   ÚmappingZ	eachStaterd   rµ   r   r%   Úunserialize   s   
ÿ
zFMethodicalMachine.unserializer.<locals>.decorator.<locals>.unserializer   )r¶   r»   rR   r¸   r%   r°   ÿ  s   z1MethodicalMachine.unserializer.<locals>.decoratorNr   r²   r   rR   r%   Úunserializerû  s   zMethodicalMachine.unserializerr'   r£   c                 C  s   t | j| jƒS r-   )r£   rª   r«   rR   r   r   r%   Ú	_setTrace  s   zMethodicalMachine._setTracec                 C  s*   ddl m} || jdd„ dd„ dd„ d�S )	a  
        Generate a L{graphviz.Digraph} that represents this machine's
        states and transitions.

        @return: L{graphviz.Digraph} object; for more information, please
            see the documentation for
            U{graphviz<https://graphviz.readthedocs.io/>}

        r   )ÚmakeDigraphc                 S  rP   r-   rQ   )r™   r   r   r%   rŸ   "  ó    z-MethodicalMachine.asDigraph.<locals>.<lambda>c                 S  rP   r-   rQ   )r>   r   r   r%   rŸ   #  r¿   c                 S  rP   r-   rQ   )rG   r   r   r%   rŸ   $  r¿   )ZstateAsStringZinputAsStringZoutputAsStringN)Z
_visualizer¾   rª   )r.   r¾   r   r   r%   Ú	asDigraph  s   
üzMethodicalMachine.asDigraphr-   )FFN)r­   r<   r®   r<   r=   r   )r'   r£   )rL   rV   rW   rX   r¬   r‹   r3   r™   r>   rG   rM   r¹   r¼   Úpropertyr½   rÀ   r   r   r   r%   r8     s&    

ÿ 



r8   )r[   r\   r]   rO   r^   r_   r'   r`   )r1   r:   r'   rF   )r–   r—   r'   r˜   )7Ú
__future__r   ÚcollectionsÚsysÚdataclassesr   r   Ú	functoolsr   Úinspectr   r    Ú	itertoolsr   Útypingr	   r
   r   r   r   Úversion_infoZtyping_extensionsr   Z_corer   r   r   r   Z_introspectionr   Ú
namedtupler   r&   r,   r3   r\   r5   re   rf   rh   rl   r|   r}   r~   r?   rŽ   rO   ZStringOutputTracerr•   rY   r¢   r£   r¨   r©   r8   r   r   r   r%   Ú<module>   sR   
þ
=
)2!
