
    BVh
B                     b   d Z ddlZddlZddlZddlmZ ddlmZ ddlmZ ddlmZ  G d dej                        Z
 G d	 d
e      Z G d d ej                  dd            Z G d de      Z G d de      Z G d de      Z G d deej$                        Z G d deej(                        Zy)z3A node transformer that includes utilities for SCT.    N)anno)parser)pretty_printer)	templatesc                       e Zd ZdZdZdZdZy)AnalysisLevelr            N)__name__
__module____qualname__NONEACTIVITYDEFINEDNESSLIVENESS     \/home/dcms/DCMS/lib/python3.12/site-packages/tensorflow/python/autograph/pyct/transformer.pyr   r      s    	
$(+(r   r   c                       e Zd ZdZd Zy)Contexta  Contains information about a source code transformation.

  This object is mutable, and is updated during conversion. Not thread safe.

  Attributes:
    info: EntityInfo, immutable.
    namer: naming.Namer.
    current_origin: origin_info.OriginInfo, holds the OriginInfo of the last
      AST node to be processed successfully. Useful for error handling.
    user: An user-supplied context object. The object is opaque to the
      infrastructure, but will pe passed through to all custom transformations.
  c                 <    || _         || _        d | _        || _        y N)infonamercurrent_originuser)selfr   r   user_contexts       r   __init__zContext.__init__3   s    DIDJDDIr   N)r   r   r   __doc__r    r   r   r   r   r   %   s    r   r   c                       e Zd ZdZy)
EntityInfoa  Contains information about a Python entity.

  Immutable.

  Examples of entities include functions and classes.

  Attributes:
    name: The name that identifies this entity.
    source_code: The entity's source code.
    source_file: The entity's source file.
    future_features: Tuple[Text], the future features that this entity was
      compiled with. See
      https://docs.python.org/2/reference/simple_stmts.html#future.
    namespace: Dict[str, ], containing symbols visible to the entity (excluding
      parameters).
  N)r   r   r   r!   r   r   r   r#   r#   ;   s    
  r   r#   )namesource_codesource_filefuture_features	namespacec                   p    e Zd ZdZd Zd Zd Zd Zd Ze	d        Z
e	d        Ze	d	        Zd
 Zd Zd Zy)_StateStacka  Templated context manager.

  This class provides syntactic sugar for a stack of objects of known
  type. It allows accessing attributes of the object at the top of the stack
  directly against this object, which allows for very terse syntax.

  For example, this code:

    stack = _StateStack(Foo)
    stack.enter()
    stack.bar

  Is equivalent to:

    stack = []
    stack.append(Foo())
    foo = stack[-1]
    foo.bar

  See _State for more on how this is used.

  Attributes:
    type: Any, the type of objects that this stack holds
    level: int, the current stack depth
    stack: List[Any], the actual stack
    value: Any, the instance of the object at the top of the stack
  c                     t         j                  | d|       t         j                  | dg        t        |d      s| j                          y y )Ntype_stackno_root)object__setattr__hasattrenter)r   type_s     r   r    z_StateStack.__init__p   s@     tVU+
tXr*5)$
jjl %r   c                 &    | j                          | S r   )r2   r   s    r   	__enter__z_StateStack.__enter__x   s    JJLKr   c                 $    | j                          y r   )exit)r   exc_type	exc_value	tracebacks       r   __exit__z_StateStack.__exit__|   s    IIKr   c                 V    | j                   j                  | j                                y r   )r-   appendr,   r5   s    r   r2   z_StateStack.enter   s    KKtyy{#r   c                 8    | j                   j                          y r   )r-   popr5   s    r   r8   z_StateStack.exit   s    KKOOr   c                     | j                   S r   r-   r5   s    r   stackz_StateStack.stack   s    ;;r   c                 ,    t        | j                        S r   )lenr-   r5   s    r   levelz_StateStack.level   s    t{{r   c                      | j                   d   S NrB   r5   s    r   valuez_StateStack.value   s    ;;r?r   c                 ,    t        | j                        S r   )iterr-   r5   s    r   __iter__z_StateStack.__iter__   s    r   c                 4    t        | j                  d   |      S rH   )getattrr-   r   keys     r   __getattr__z_StateStack.__getattr__   s    4;;r?C((r   c                 8    t        | j                  d   ||       y rH   )setattrr-   )r   rQ   rJ   s      r   r0   z_StateStack.__setattr__   s    DKKOS%(r   N)r   r   r   r!   r    r6   r<   r2   r8   propertyrC   rF   rJ   rM   rR   r0   r   r   r   r*   r*   S   sk    8$      ))r   r*   c                       e Zd ZdZd Zd Zy)_Statea  Syntactic sugar for accessing an instance of a StateStack context manager.

  This structure offers syntactic sugar over a dict of stacks of objects
  of known type. These structures are useful to keep state during AST walks.
  Multiple different scopes can be tracked in parallel. For example:

    s = _State()

    s[foo].enter()
    s[bar].enter()  # this will not affect s[foo]

  Element access has special semantics:
    * keys are a data type
    * element values are _StateStack(type=key) objects
    * missing elements are automatically added, similarly to defaultdict

  For example, the following block :

    _State s
    s[Foo]

  Is equivalent to:

    s = {}
    if Foo not in s:
      s[Foo] = Foo()
    s[Foo]

  See Base for how it's used.
  c                     i | _         y r   )_valuer5   s    r   r    z_State.__init__   s	    DKr   c                 l    || j                   vrt        |      | j                   |<   | j                   |   S r   )rY   r*   rP   s     r   __getitem__z_State.__getitem__   s0    
$++$S)dkk#;;sr   N)r   r   r   r!   r    r[   r   r   r   rW   rW      s    >r   rW   c                   *    e Zd ZdZd Zd Zd ZddZy)NodeStateTrackera<  Base class for general-purpose Python code transformation.

  This abstract class provides helpful functions, like state tracking within
  the scope of arbitrary node, helpers for processing code blocks, debugging,
  mapping of transformed code to original code, and others.

  Scope-local state tracking: to keep state across nodes, at the level of
  (possibly nested) scopes, use enter/exit_local_scope and set/get_local.
  You must call enter/exit_local_scope manually, but the transformer detects
  when they are not properly paired.

  The transformer allows keeping state across calls that is local
  to arbitrary nodes and their descendants, using the self.state attribute.
  Multiple independent scopes are allowed and automatically constructed.

  For example, to keep track of the `If` node that encloses any `Name` node,
  one can write:

  ```
    class FooType(object):

      def __init__(self):
        self.foo_property = None

    class DummyTransformer(NodeStateTracker, ast.NodeTransformer):

      def visit_If(self, node):
        self.state[FooType].enter()
        self.state[FooType].foo_property = node
        node = self.veneric_visit(node)
        self.state[FooType].exit()
        return node

      def visit_Name(self, node):
        self.state[FooType].foo_property  # will hold the innermost enclosing if
  ```

  Alternatively, the `enter()`/`exit()` calls can be managed by a `with`
  statement:

  ```
      def visit_If(self, node):
        with self.state[FooType] as foo:
          foo.foo_property = node
          return self.generic_visit(node)
  ```
  c                 L    d| _         d| _        || _        t               | _        y)zjInitialize the transformer.

    Subclasses should call this.

    Args:
      ctx: A Context object.
    r   N)_lineno_col_offsetctxrW   state)r   ra   s     r   r    zNodeStateTracker.__init__   s%     DLDDH DJr   c                 D    	 t        t        j                  |             |S )z3Helper method useful for debugging. Prints the AST.)printr   fmtr   nodes     r   debug_printzNodeStateTracker.debug_print
  s    Nt$%Kr   c                 D    	 t        t        j                  |             |S )z;Helper method useful for debugging. Prints the AST as code.)rd   r   unparserf   s     r   debug_print_srcz NodeStateTracker.debug_print_src  s    FNN4 !Kr   Nc                     |yg }|}|D ]n  }|r |        | j                  |      }|r|r ||      \  }}nd}|r9t        |t        t        f      r|j	                  |       n|j                  |       |m|}p |S )a%  A more powerful version of generic_visit for statement blocks.

    An example of a block is the body of an if statement.

    This function allows specifying a postprocessing callback (the
    after_visit argument) argument which can be used to move nodes to a new
    destination. This is done by after_visit by returning a non-null
    second return value, e.g. return new_node, new_destination.

    For example, a transformer could perform the following move:

        foo()
        bar()
        baz()

        foo()
        if cond:
          bar()
          baz()

    The above could be done with a postprocessor of this kind:

        def after_visit(node):
          if node_is_function_call(bar):
            new_container_node = build_cond()
            new_container_node.body.append(node)
            return new_container_node, new_container_node.body
          else:
            # Once we set a new destination, all subsequent items will be
            # moved to it, so we don't need to explicitly handle baz.
            return node, None

    Args:
      nodes: enumerable of AST node objects. If None, the function returns None.
      before_visit: optional callable that is called before visiting each item
        in nodes
      after_visit: optional callable that takes in an AST node and returns a
        tuple (new_node, new_destination). It is called after visiting each item
        in nodes. Is used in the same was as the visit_* methods: new_node will
        replace the node; if not None, new_destination must be a list, and
        subsequent nodes will be placed in this list instead of the list
        returned by visit_block.

    Returns:
      A list of AST node objects containing the transformed items from nodes,
      except those nodes that have been relocated using after_visit.
    N)visit
isinstancelisttupleextendr>   )	r   nodesbefore_visitafter_visitresultsnode_destinationrg   replacementnew_destinations	            r   visit_blockzNodeStateTracker.visit_block  s    ` }G +	JJt$k	'2;'?$_	kD%=1

!
!+
.

!
!+
. 
	$*)+* Nr   )NN)r   r   r   r!   r    rh   rk   ry   r   r   r   r]   r]      s    .d&Jr   r]   c                   .     e Zd ZdZd Zd Z fdZ xZS )BasezBase class for general-purpose Python-to-Python code transformation.

  This is an extension of ast.NodeTransformer that provides the additional
  functions offered by NodeStateTracker.
  c                 6    d}t        j                  |||      S )Nz
      target = expression
    )target
expression)r   replace)r   r}   r~   templates       r   create_assignmentzBase.create_assignmentk  s     H XfLLr   c                    t        |t        t        f      s|f}|D ]  }t        |t        j                  t        j
                  f      rt        t        |j                              D ]  }|j                  |   }t        |t        j                  t        j
                  f      r|j                  |   }n*t        j                  ||t        j                               }| j                  |||         |||        y)a  Applies a function to each individual assignment.

    This function can process a possibly-unpacked (e.g. a, b = c, d) assignment.
    It tries to break down the unpacking if possible. In effect, it has the same
    effect as passing the assigned values in SSA form to apply_fn.

    Examples:

    The following will result in apply_fn(a, c), apply_fn(b, d):

        a, b = c, d

    The following will result in apply_fn(a, c[0]), apply_fn(b, c[1]):

        a, b = c

    The following will result in apply_fn(a, (b, c)):

        a = b, c

    It uses the visitor pattern to allow subclasses to process single
    assignments individually.

    Args:
      targets: list, tuple of or individual AST node. Should be used with the
        targets field of an ast.Assign node.
      values: an AST node.
      apply_fn: a function of a single argument, which will be called with the
        respective nodes of each single assignment. The signature is
        apply_fn(target, value), no return value.
    )ra   N)rn   ro   rp   gastTupleListrangerE   elts	SubscriptStoreapply_to_single_assignments)r   targetsvaluesapply_fnr}   i	target_elvalue_els           r   r   z Base.apply_to_single_assignmentsr  s    @ ge}-
g !	FTZZ3	4s6;;'( 	JAkk!n)TYY 78{{1~H~~faTZZ\BH

*
*9h
I	J 	 !r   c                    t        |t        j                        s%dj                  t	        |            }t        |      t        j                  |t        j                  j                        r|S | j                  j                  }t        j                  |t        j                  j                        r=t        j                  |t        j                  j                        | j                  _        	 t        |t        j                        }|r|j                  }t         t"        | K  |      }|rrt        |t        j                        rX|j                  urJt        |j                  t&        t(        t        j*                  t        j,                  f      r|j                  }||ur|t        j                  |t        j                  j                  |      }||}t        |t&        t(        f      r|}n|f}|D ]`  }	t        j                  |	t        j                  j                        r2t        j.                  |	t        j                  j                  |       b || j                  _        |S # || j                  _        w xY w)Nzjinvalid value for "node": expected "ast.AST", got "{}"; to visit lists of nodes, use "visit_block" insteaddefault)rn   r   ASTformatr,   
ValueErrorr   hasannoBasicSKIP_PROCESSINGra   r   ORIGINgetannoExprrJ   superr{   rm   ro   rp   Assign	AugAssignsetanno)r   rg   msgparent_originprocessing_expr_nodeentry_expr_valueresultinherited_originnodes_to_adjustn	__class__s             r   rm   z
Base.visit  s   dDHH%@AGdB 
 sO||D$**445kHH++M||D$**++, $T4::3D3D Edhh!.'dii8	::T4&t,f :fdii#@<<// fllUDKK@B<<& 
t	 2<<$**##]<'"/u.$O%iO" Ca<<4::#4#45ll1djj//1ABC !.dhhM !.dhhs   3D8I0 ,1I0 0J)r   r   r   r!   r   r   rm   __classcell__r   s   @r   r{   r{   d  s    M-!^6 6r   r{   c                   B     e Zd ZdZ fdZd Zed        Z fdZ xZ	S )CodeGeneratoraB  Base class for general-purpose Python-to-string code transformation.

  Similar to Base, but outputs arbitrary strings instead of a Python AST.

  This uses the same visitor mechanism that the standard NodeVisitor uses,
  meaning that subclasses write handlers for the different kinds of nodes.
  New code is generated using the emit method, which appends to a code buffer
  that can be afterwards obtained from code_buffer.

  Example:

    class SimpleCodeGen(CodeGenerator):

      def visitIf(self, node):
        self.emit('if ')
        self.visit(node.test)
        self.emit(' { ')
        self.visit(node.body)
        self.emit(' } else { ')
        self.visit(node.orelse)
        self.emit(' } ')

    node = ast.parse(...)
    gen = SimpleCodeGen()
    gen.visit(node)
    # gen.code_buffer contains the resulting code
  c                 H    t         t        |   |       d| _        i | _        y )N )r   r   r    _output_code
source_map)r   ra   r   s     r   r    zCodeGenerator.__init__  s!    	-',DDOr   c                 .    | xj                   |z  c_         y r   r   )r   codes     r   emitzCodeGenerator.emit  s    r   c                     | j                   S r   r   r5   s    r   code_bufferzCodeGenerator.code_buffer   s    r   c                    t        j                  |t         j                  j                        ry | j                  j
                  }t        | j                        }t        j                  |t         j                  j                        r=t        j                  |t         j                  j                        | j                  _        	 t        t        | 3  |      }t        | j                        }||z
  rCt        j                  |t         j                  j                  |      }||| j                  ||f<   ||| j                  _        S # || j                  _        w xY w)Nr   )r   r   r   r   ra   r   rE   r   r   r   r   r   rm   r   )r   rg   r   
eof_beforeret	eof_afterr   r   s          r   rm   zCodeGenerator.visit  s    ||D$**445HH++MT&&'J||D$**++, $T4::3D3D Edhh.-,T2c d''(i	i	<<$**##]<'5E$//:y1
2 -dhhdhhs   A1E E)
r   r   r   r!   r    r   rU   r   rm   r   r   s   @r   r   r     s0    8  . .r   r   )r!   collectionsenumr    tensorflow.python.autograph.pyctr   r   r   r   IntEnumr   r/   r   
namedtupler#   r*   rW   r]   NodeTransformerr{   NodeVisitorr   r   r   r   <module>r      s    :    1 3 ; 6DLL f ,KNP0E)& E)P&V &R\v \@sT11 sl@.$d&6&6 @.r   