
    ~b=                        d dl Z d dlmZ d dlmZ d dlmZ d dlZddl	m
Z
mZ ddlmZ  e j                  dg d	      Zd
 Zd Zd Z ej&                  d       G d de             Zd Zd Zd Zd Zd Z ej&                  dd       G d de             Z ej&                  d       G d de             Z ej&                  dd       G d de             Z e       Zd Z G d d e      Z y)!    Nwraps)count)getfullargspec   )Transitioner	Automaton)preserveNameArgSpecargsvarargsvarkwdefaults
kwonlyargskwonlydefaultsannotationsc                    t        |       }t        t        |j                        |j                  |j
                  |j                  r|j                  ndt        |j                        |j                  r#t        |j                  j                               ndt        |j                  j                                     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   )getArgsSpecr   tupler   r   r   r   r   r   itemsr   )funcspecs     5/usr/lib/python3/dist-packages/automat/_methodical.py_getArgSpecr      s     tD499jj"&--R) "" $%%++-.(*$**0023     c                     t        | j                  | j                  z   | j                  rdndz   | j                  rdndz   | j
                  z         S )a0  
    Get the name of all arguments defined in a function signature.

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

    :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**kwargs)setr   r   r   r   r   )r   s    r   _getArgNamesr    ,   sV     		
//	:2	/ !JJ=B	0 

		 r   c                 .     t                f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                      | fi |S Nr   )selfkwfs     r   gz_keywords_only.<locals>.gI   s    }}r   r   )r&   r'   s   ` r   _keywords_onlyr(   ?   s      1X Hr   T)frozenc                       e Zd ZdZ ej
                  d      Z ej
                         Z ej
                  d      Zdde	fdZ
d Zy)MethodicalStatez-
    A state for a L{MethodicalMachine}.
    FreprNc                    || }|g }t        |j                        }|D ]  }t        |j                        }|j                  |      r*t        dj	                  |j
                  j                  |j
                  j                  t        |j
                        t        |j
                                     | j                  j                  | ||||       y)ac  
        Declare a state transition within the :class:`automat.MethodicalMachine`
        associated with this :class:`automat.MethodicalState`:
        upon the receipt of the `input`, enter the `state`,
        emitting each output in `outputs`.

        :param MethodicalInput input: The input triggering a state transition.
        :param MethodicalState enter: The resulting state.
        :param Iterable[MethodicalOutput] outputs: The outputs to be triggered
            as a result of the declared state transition.
        :param Callable 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})inputoutputinputSignatureoutputSignature)
r    argSpecissubset	TypeErrorformatmethod__name__r   machine_oneTransition)r$   r/   enteroutputs	collector	inputArgsr0   
outputArgss           r   uponzMethodicalState.uponX   s    & =E?G /	 	F%fnn5J&&y1228&#ll33%}}55'25<<'@(3FMM(B	 39 3 	 	##D%Kr   c                 .    | j                   j                  S r#   r7   r8   r$   s    r   _namezMethodicalState._name~       {{###r   )r8   
__module____qualname____doc__attribr9   r7   
serializedlistr@   rD   r   r   r   r+   r+   O   sI     dgg5!GTWWYFe$J $dd $LL$r   r+   c                 j    t        | |d      }|#t        ||j                        }t        | ||       |S )z
    Get a L{Transitioner}
    N)getattrr   initialStatesetattr)oselfsymbol	automatontransitioners       r   _transitionerFromInstancerU      sB     5&$/L#""
 	v|,r   c                       y r#   r   r   r   r   _emptyrW      s    r   c                       y)	docstringNr   r   r   r   
_docstringrZ      s    r   c                     |j                   j                  t        j                   j                  t        j                   j                  fvrt	        d      y )Nzfunction body must be empty)__code__co_coderW   rZ   
ValueError)inst	attributer&   s      r   assertNoCodera      sG     	zz&//"9"9","5"5"="="? ?677?r   c                 f   t        t        |j                  dd |             }|j                  r| }n#|D cg c]  \  }}||j                  v s| }}}t        |      }|D ]  \  }	}
||	|
fz  } t        |j                  ddd   |j                  ddd         }|D ci c]  \  }}||vs|| }}}|j                  |       |j                  r|}||fS |j                  dd |j                  z   }|j                         D ci c]  \  }}||v r|| }}}||fS c c}}w c c}}w c c}}w )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   N)	r   zipr   r   r   updater   r   r   )r   kwargs	inputSpec
outputSpec
named_argsreturn_argsnvpassed_arg_namesnamevaluer   full_kwargsreturn_kwargsall_accepted_namess                  r   _filterArgsrs      sf    s9>>!"-t45J &0HTQ1
3GqHH V}! *eT5M)*9>>$B$'););DbD)ABH$,JDAq9I0I1a4JKJv# %%	 (__QR0:3H3HH*5*;*;*= 5$!Q!33 A 5 5 %%' I K5s   D!D!"D'/D'	D-F)eqhashc                   $   e Zd ZdZ ej
                  d      Z ej
                  e      Z ej
                  d      Z	 ej
                   ej                  e      d      Z ej
                  dd      Zej                  d        Zdd	Zd
 Zy)MethodicalInputz.
    An input for a L{MethodicalMachine}.
    Fr,   )	validator)defaultr-   initr-   c                 ,    t        | j                        S r#   r   r7   rC   s    r   _buildArgSpeczMethodicalInput._buildArgSpec       4;;''r   Nc                      t         j                   j                        t         j                        t         j                         f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.
        c                  d    j                   g| i | j                  }j                        \  }}j                  |   }g }|D ]\  }|r ||j	                                t        | |j                  |j                        \  }}	 |g|i |	}
|j                  |
       ^  ||      S r#   )r7   _state
transition
collectorsrD   rs   r3   append)r   rf   previousStater<   	outTracerr=   valuesr0   akro   rQ   r$   rT   s              r   doInputz(MethodicalInput.__get__.<locals>.doInput   s     DKK///(//M#/#:#:4#@ Wi6IF! %flln-"4v~~N1u.q.A.e$% V$$r   )rU   rR   rS   r
   r7   r   )r$   rQ   typer   rT   s   ``  @r   __get__zMethodicalInput.__get__   sR     115A	dkk	"	t{{		% 
 
#	% r   c                 .    | j                   j                  S r#   rB   rC   s    r   rD   zMethodicalInput._name   rE   r   r#   )r8   rF   rG   rH   rI   rJ   rS   ra   r7   rR   Factorydictr   r3   ry   r~   r   rD   r   r   r   rw   rw      s     U#ITWW|,FTWW% Fd!3%@Jdgg5u-G__( (2$r   rw   c                       e Zd ZdZ ej
                  d      Z ej
                         Z ej
                  dd      Zej                  d        Z
d
dZd Zd	 Zy)MethodicalOutputz/
    An output for a L{MethodicalMachine}.
    Fr,   rz   c                 ,    t        | j                        S r#   r}   rC   s    r   r~   zMethodicalOutput._buildArgSpec  r   r   Nc                 v    t        dj                  |j                  | j                  j                              )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.)clsr7   )AttributeErrorr6   r8   r7   r$   rQ   r   s      r   r   zMethodicalOutput.__get__  s=     DDJFMM{{++ EK E
 	
r   c                 .     | j                   |g|i |S )z-
        Call the underlying method.
        )r7   )r$   rQ   r   rf   s       r   __call__zMethodicalOutput.__call__  s     t{{5242622r   c                 .    | j                   j                  S r#   rB   rC   s    r   rD   zMethodicalOutput._name  rE   r   r#   )r8   rF   rG   rH   rI   rJ   r9   r7   r3   ry   r~   r   r   rD   r   r   r   r   r      s]     dgg5!GTWWYFdgg5u-G__( (

3$r   r   c                   `    e Zd Z ej                  d      Z ej                  d      ZddZy)MethodicalTracerFr,   Nc                 T    t        || j                  | j                        fd}|S )Nc                 (    j                  |        y r#   )setTrace)tracerrT   s    r   r   z*MethodicalTracer.__get__.<locals>.setTrace'  s    !!&)r   )rU   rR   rS   )r$   rQ   r   r   rT   s       @r   r   zMethodicalTracer.__get__$  s'    015A	*r   r#   )r8   rF   rG   rI   rJ   rS   rR   r   r   r   r   r   r     s'    U#ITWW% Fr   r   c                  8    dt        t        t                    z   S )z,
    Create a unique Python identifier.
    _symbol_)strnextcounterr   r   r   gensymr   .  s     DM***r   c                       e Zd ZdZd ZddZe	 	 dd       Zed        Zed        Z	d Z
ed	        Zed
        Zed        Zd Zy)MethodicalMachinezj
    A :class:`MethodicalMachine` is an interface to an `Automaton`
    that uses methods on a class.
    c                 N    t               | _        i | _        t               | _        y r#   )r	   
_automaton	_reducersr   _symbolrC   s    r   __init__zMethodicalMachine.__init__<  s    #+xr   Nc                      |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.
        z.MethodicalMachine is an implementation detail.)r   r   s      r   r   zMethodicalMachine.__get__B  s!      @B Br   c                       f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 bool initial: is this state the initial state?
            Only one state on this :class:`automat.MethodicalMachine`
            may be an initial state; more than one is an error.

        :param bool 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 Hashable serialized: a serializable value
            to be used to represent this state to external systems.
            This value should be hashable;
            :py:func:`unicode` is a good type to use.
        c                 J    t        |       }r|j                  _        |S )N)r9   r7   rK   )r+   r   rO   )stateMethodstateinitialr$   rK   s     r   	decoratorz*MethodicalMachine.state.<locals>.decoratord  s+    #D+6/9;E /4,Lr   r   )r$   r   terminalrK   r   s   `` ` r   r   zMethodicalMachine.stateN  s    ,	 r   c                       fd}|S )zM
        Declare an input.

        This is a decorator for methods.
        c                 H    t        j                  | j                        S )N)rS   r7   rR   )rw   r   r   )inputMethodr$   s    r   r   z*MethodicalMachine.input.<locals>.decoratoru  s     "T__*5*.,,8 8r   r   r$   r   s   ` r   r/   zMethodicalMachine.inputn  s    	8 r   c                       fd}|S )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                     t        |       S )N)r9   r7   )r   )outputMethodr$   s    r   r   z+MethodicalMachine.output.<locals>.decorator  s    #DFFr   r   r   s   ` r   r0   zMethodicalMachine.output|  s    	Gr   c                 p    | j                   j                  |||t        |             ||j                  |<   y)z.
        See L{MethodicalState.upon}.
        N)r   addTransitionr   r   )r$   
startState
inputTokenendStateoutputTokensr=   s         r   r:   z MethodicalMachine._oneTransition  s4    & 	%%j*h&+L&9	;,5
j)r   c                       fd}|S )


        c                 2     t                fd       }|S )Nc                     t        | j                  j                        } | |j                  j                        S r#   )rU   r   r   r   rK   )rQ   rT   	decorateer$   s     r   	serializezBMethodicalMachine.serializer.<locals>.decorator.<locals>.serialize  s6    89= J (;(;(F(FGGr   r   )r   r   r$   s   ` r   r   z/MethodicalMachine.serializer.<locals>.decorator  s$    9H H r   r   r   s   ` r   
serializerzMethodicalMachine.serializer  s    
	 r   c                       fd}|S )r   c                 2     t                fd       }|S )Nc                      | g|i |}i }j                   j                         D ]  }|||j                  <    t        | j                  j                         }||   |_        y r#   )r   statesrK   rU   r   r   )	rQ   r   rf   r   mapping	eachStaterT   r   r$   s	          r   unserializezFMethodicalMachine.unserializer.<locals>.decorator.<locals>.unserialize  sp    !%9$9&9!%!7!7!9 >I4=GI001>84<< :&-en#r   r   )r   r   r$   s   ` r   r   z1MethodicalMachine.unserializer.<locals>.decorator  s"    9  r   r   r   s   ` r   unserializerzMethodicalMachine.unserializer  s    
	 r   c                 B    t        | j                  | j                        S r#   )r   r   r   rC   s    r   	_setTracezMethodicalMachine._setTrace  s    >>r   c                 @    ddl m}  || j                  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                 .    | j                   j                  S r#   rB   )r   s    r   <lambda>z-MethodicalMachine.asDigraph.<locals>.<lambda>      (=(= r   c                 .    | j                   j                  S r#   rB   )r/   s    r   r   z-MethodicalMachine.asDigraph.<locals>.<lambda>  r   r   c                 .    | j                   j                  S r#   rB   )r0   s    r   r   z-MethodicalMachine.asDigraph.<locals>.<lambda>  s    &--*@*@ r   )stateAsStringinputAsStringoutputAsString)
_visualizer   r   )r$   r   s     r   	asDigraphzMethodicalMachine.asDigraph  s$     	,OO==@	
 	
r   r#   )FFN)r8   rF   rG   rH   r   r   r(   r   r/   r0   r:   r   r   propertyr   r   r   r   r   r   r   6  s    
 	 ,1 > 
 
  60    $ ? ?
r   r   )!collections	functoolsr   	itertoolsr   inspectr   r   rI   _corer   r	   _introspectionr
   
namedtupler   r   r    r(   sobjectr+   rU   rW   rZ   ra   rs   rw   r   r   r   r   r   r   r   r   <module>r      s      1  * ( !+
 
  -N O
0&  t/$f /$ /$d	8"%&P 5u($f ($ ($V t $v  $  $D 5u
v 
 
 '+b
 b
r   