
    BVh                        d Z ddlZddlZddlZddlZddlZddlZddlZddlZddl	Z	 ej                  d      Z ej                  d      ZdZdZdZ ej                   dd	d
g      Z ej$                         fdZddZd Zd Zd Zd Z G d d      Z G d de      Z G d dej6                        Z G d d      Z G d d      Z G d de      Z G d d      Z y) zEUpgrader for Python scripts according to an API change specification.    Nz^\s*(\[).*$z['\"]INFOWARNINGERRORImportRenamenew_nameexcluded_prefixesc                 >   | j                  d      }|j                          t        j                  |j	                         t        j
                               }|r;t        j                  ||j	                         t        j
                               }|r;||_        |S )a  Make an Attribute or Name node for name.

  Translate a qualified name into nested Attribute nodes (and a Name node).

  Args:
    name: The name to translate to a node.
    ctx: What context this name is used in. Defaults to Load()

  Returns:
    A Name or Attribute node.
  .)idctx)valueattrr   )splitreverseastNamepopLoad	Attributer   )namer   namesnodes       X/home/dcms/DCMS/lib/python3.12/site-packages/tensorflow/tools/compatibility/ast_edits.pyfull_name_noder   +   sj     **S/%--/	UYY[chhj	1$==t%))+388:FD 	 $(	+    c                    |0| j                   D ]!  }|j                  |k(  sd|j                  fc S  |Td}| j                  D ]C  }t        j
                  dd dk\  rt        |t        j                        r4||k(  rd|fc S |dz  }E y)a  Get the value of an argument from a ast.Call node.

  This function goes through the positional and keyword arguments to check
  whether a given argument was used, and if so, returns its value (the node
  representing its value).

  This cannot introspect *args or **args, but it safely handles *args in
  Python3.5+.

  Args:
    node: The ast.Call node to extract arg values from.
    arg_name: The name of the argument to extract.
    arg_pos: The position of the argument (in case it's passed as a positional
      argument).

  Returns:
    A tuple (arg_present, arg_value) containing a boolean indicating whether
    the argument is present, and its value in case it is.
  NTr               )FN)	keywordsargr   argssysversion_info
isinstancer   Starred)r   arg_namearg_poskwidxr#   s         r   get_arg_valuer-   B   s    * mm  	8	bhh 
 
Cyy 			"1		'JsCKK,H	c{	Qhc 
r   c                     t         j                  dd dk\  r.| j                  D ]  }t        |t        j
                        s y y| j                  ryy)a|  Check if an ast.Call node uses arbitrary-length positional *args.

  This function works with the AST call node format of Python3.5+
  as well as the different AST format of earlier versions of Python.

  Args:
    node: The ast.Call node to check arg values for.

  Returns:
    True if the node uses starred variadic positional args or keyword args.
    False if it does not.
  Nr   r   TF)r%   r&   r$   r'   r   r(   starargs)r   r#   s     r   uses_star_args_in_callr0   i   sQ     	bqV#yy 	C	% 
 }}	r   c                     t         j                  dd dk\  r | j                  D ]  }|j                   y y| j                  ryy)at  Check if an ast.Call node uses arbitrary-length **kwargs.

  This function works with the AST call node format of Python3.5+
  as well as the different AST format of earlier versions of Python.

  Args:
    node: The ast.Call node to check arg values for.

  Returns:
    True if the node uses starred variadic positional args or keyword args.
    False if it does not.
  Nr   r   TF)r%   r&   r"   r#   kwargs)r   keywords     r   uses_star_kwargs_in_callr4      sM     	bqV#== 		 
 {{	r   c                 2    t        |       xs t        |       S )a}  Check if an ast.Call node uses arbitrary-length *args or **kwargs.

  This function works with the AST call node format of Python3.5+
  as well as the different AST format of earlier versions of Python.

  Args:
    node: The ast.Call node to check arg values for.

  Returns:
    True if the node uses starred variadic positional args or keyword args.
    False if it does not.
  )r0   r4   )r   s    r    uses_star_args_or_kwargs_in_callr6      s     
 	%	G)A$)GGr   c                 L    |j                   D ]  }| j                  |      s y y)zCheck if this module import should not be renamed.

  Args:
    module: (string) module name.
    import_rename_spec: ImportRename instance.

  Returns:
    True if this import should not be renamed according to the
    import_rename_spec.
  TF)r   
startswith)moduleimport_rename_specexcluded_prefixs      r   excluded_from_module_renamer<      s/     ,== o) 
r   c                       e Zd ZdZd Zd Zy)APIChangeSpeca  This class defines the transformations that need to happen.

  This class must provide the following fields:

  * `function_keyword_renames`: maps function names to a map of old -> new
    argument names
  * `symbol_renames`: maps function names to new function names
  * `change_to_function`: a set of function names that have changed (for
    notifications)
  * `function_reorders`: maps functions whose argument order has changed to the
    list of arguments in the new order
  * `function_warnings`: maps full names of functions to warnings that will be
    printed out if the function is used. (e.g. tf.nn.convolution())
  * `function_transformers`: maps function names to custom handlers
  * `module_deprecations`: maps module names to warnings that will be printed
    if the module is still used after all other transformations have run
  * `import_renames`: maps import name (must be a short name without '.')
    to ImportRename instance.

  For an example, see `TFAPIChangeSpec`.
  c                     |g g fS )zEPreprocess a parse tree. Return a preprocessed node, logs and errors. )self	root_nodes     r   
preprocesszAPIChangeSpec.preprocess   s    b"r   c                      y)zRestore this APIChangeSpec to before it preprocessed a file.

    This is needed if preprocessing a file changed any rewriting rules.
    Nr@   rA   s    r   clear_preprocessingz!APIChangeSpec.clear_preprocessing   s    
 	r   N)__name__
__module____qualname____doc__rC   rF   r@   r   r   r>   r>      s    ,	r   r>   c                       e Zd ZdZd Zy)NoUpdateSpecz?A specification of an API change which doesn't change anything.c                     i | _         i | _        i | _        i | _        i | _        i | _        i | _        i | _        i | _        y N)	function_handlefunction_reordersfunction_keyword_renamessymbol_renamesfunction_warningschange_to_functionmodule_deprecationsfunction_transformersimport_renamesrE   s    r   __init__zNoUpdateSpec.__init__   sJ    DD$&D!DD D!D!#DDr   N)rG   rH   rI   rJ   rX   r@   r   r   rL   rL      s
    G	r   rL   c                        e Zd ZdZd Z fdZed        Zed        Zed        Z	ed        Z
ed        Zd	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Z xZS )_PastaEditVisitorzAST Visitor that processes function calls.

  Updates function calls from old API version to new API version using a given
  change spec.
  c                 .    || _         g | _        g | _        y rN   )_api_change_spec_log_stackrA   api_change_specs     r   rX   z_PastaEditVisitor.__init__   s    +DDIDKr   c                     | j                   j                  |       t        t        |   |       | j                   j                          y rN   )r^   appendsuperrZ   visitr   )rA   r   	__class__s     r   rd   z_PastaEditVisitor.visit   s3    KKt	
T(.KKOOr   c                 Z    | j                   D cg c]  }|d   t        k(  s| c}S c c}w Nr   )r]   r   rA   logs     r   errorsz_PastaEditVisitor.errors   s$    998CA%C888   ((c                 Z    | j                   D cg c]  }|d   t        k(  s| c}S c c}w rg   )r]   r   rh   s     r   warningsz_PastaEditVisitor.warnings  s%    99:CA'(9C:::rk   c                 d    | j                   D cg c]  }|d   t        t        fv s| c}S c c}w rg   )r]   r   r   rh   s     r   warnings_and_errorsz%_PastaEditVisitor.warnings_and_errors  s*    99CCA7E2B(BCCCCs   --c                 Z    | j                   D cg c]  }|d   t        k(  s| c}S c c}w rg   )r]   r   rh   s     r   infoz_PastaEditVisitor.info
  s$    997CA$C777rk   c                     | j                   S rN   )r]   rE   s    r   ri   z_PastaEditVisitor.log  s    99r   c                 f    | j                   j                  ||||f       t        d||||fz         y )N%s line %d:%d: %s)r]   rb   print)rA   severitylinenocolmsgs        r   add_logz_PastaEditVisitor.add_log  s4    IIhS12	
63 <
<=r   c                 d    | j                   j                  |       |D ]  }t        d|z          y)a=  Record a log and print it.

    The log should be a tuple `(severity, lineno, col_offset, msg)`, which will
    be printed and recorded. It is part of the log available in the `self.log`
    property.

    Args:
      logs: The logs to add. Must be a list of tuples
        `(severity, lineno, col_offset, msg)`.
    rt   N)r]   extendru   )rA   logsri   s      r   add_logsz_PastaEditVisitor.add_logs  s3     	IIT '#%&'r   c                     t        | j                  |i       }|rd|z   nd}g }||v r|j                  ||          ||v r|j                  ||          d|v r|j                  |d          |S )zEGet all list entries indexed by name that apply to full_name or name.*.N*)getattrr\   rb   rA   transformer_field	full_namer   rV   	glob_nametransformerss          r   _get_applicable_entriesz)_PastaEditVisitor._get_applicable_entries%  s     $D$9$9$5r;  $tIL))/	:;))/	:;
##/45r   c                 
   t        | j                  |i       }|rd|z   nd}|j                  di       j                         }|j	                  |j                  |i              |j	                  |j                  |i              |S )zEGet all dict entries indexed by name that apply to full_name or name.r   Nr   )r   r\   getcopyupdater   s          r   _get_applicable_dictz&_PastaEditVisitor._get_applicable_dict6  s     $D$9$9$5r;  $tI(,,S"5::<L-11)R@A-11)R@Ar   c                 b   |}g }t        |t        j                        s]t        |t        j                        sy|j	                  |j
                         |j                  }t        |t        j                        s]|j	                  |j                         dj                  t        |            S )aP  Traverse an Attribute node to generate a full name, e.g., "tf.foo.bar".

    This is the inverse of `full_name_node`.

    Args:
      node: A Node of type Attribute.

    Returns:
      a '.'-delimited full-name or None if node was not Attribute or Name.
      i.e. `foo()+b).bar` returns None, while `a.b.c` would return "a.b.c".
    Nr
   )
r'   r   r   r   rb   r   r   r   joinreversed)rA   r   curritemss       r   _get_full_namez _PastaEditVisitor._get_full_nameC  s{     DEsxx(cmm,ll499ZZd	 sxx(
 
LL88HUO$$r   c                     | j                   j                  }||v rH||   \  }}|j                  d|      }| j                  ||j                  |j
                  |d|       yy)z4Adds an error to be printed about full_name at node.<function name>z requires manual check. TF)r\   rS   replacerz   rw   
col_offset)rA   r   r   rS   levelmessages         r   _maybe_add_warningz$_PastaEditVisitor._maybe_add_warningY  se    --??%%(3neW 19=g
ll5$++t5>HJr   c                     | j                   j                  }||v rL||   \  }}|j                  d|      }| j                  ||j                  |j
                  d|d|d|       yy)z3Adds a warning if full_name is a deprecated module.r   zUsing member z in deprecated module z. TF)r\   rU   r   rz   rw   r   )rA   r   r   
whole_namerm   r   r   s          r   %_maybe_add_module_deprecation_warningz7_PastaEditVisitor._maybe_add_module_deprecation_warninge  sl    $$88HH	*neW 1:>g
ll5$++tDNDMDKMN r   c           
         d}t        |j                  t        j                        r| j	                  |d|z         }| j                  d||      }t        |      }t        |j                               D ]r  \  \  }}\  }	}
t        |||      xs |\  }}|s#d}|
j                  d|xs |      }d}|rd}| j                  |	|j                  |j                  ||xs |||fz         t |S )a  Print a warning when specific functions are called with selected args.

    The function _print_warning_for_function matches the full name of the called
    function, e.g., tf.foo.bar(). This function matches the function name that
    is called, as long as the function is an attribute. For example,
    `tf.foo.bar()` and `foo.bar()` are matched, but not `bar()`.

    Args:
      node: ast.Call object
      full_name: The precomputed full name of the callable, if one exists, None
        otherwise.
      name: The precomputed name of the callable, if one exists, None otherwise.

    Returns:
      Whether an error was recorded.
    Fr   function_arg_warningsTr   z5%s called with %s argument, requires manual check: %szO%s called with *args or **kwargs that may include %s, requires manual check: %s)r'   funcr   r   r   r   r6   sortedr   r-   r   rz   rw   r   )rA   r   r   r   warnedarg_warningsvariadic_argskwargr#   r   warningpresent_warning_messagetemplates                  r   _maybe_add_call_warningz)_PastaEditVisitor._maybe_add_call_warnings  s    ( F$))S]]+&&tTD[9f ,,-D-6>L 5T:M*01C1C1E*F 
M&&ug uc2Cmjgq	!//*;Y=N$OJ2(UDKK!2dE? KK	M
M Mr   c           	      T   | j                   j                  j                  |d      }|r| j                  t        |j
                  |j                  d|d|       t        ||j                        }t        j                  ||       t        j                  j                  |||       yy)zDReplace node (Attribute or Name) with a node representing full_name.NzRenamed  to TF)r\   rR   r   rz   r   rw   r   r   r   r   copy_locationpasta	ast_utilsreplace_child)rA   parentr   r   r   new_nodes         r   _maybe_renamez_PastaEditVisitor._maybe_rename  s    $$3377	4HH
ll4doo)2H=?$((3h	$'oo##FD(;r   c                 d   || j                   j                  v rt        |t        j                        s~t        j                  |g g       }t
        j                  j                  |||       t        j                  ||       | j                  t        |j                  |j                  d|z         yy)z7Wraps node (typically, an Attribute or Expr) in a Call.zChanged %r to a function callTF)r\   rT   r'   r   Callr   r   r   r   rz   r   rw   r   )rA   r   r   r   r   s        r   _maybe_change_to_function_callz0_PastaEditVisitor._maybe_change_to_function_call  s    D))<<<) 88D"b)%%fdH=(D)T4;;4y@	Br   c                 r   | j                   j                  }||v rt        |      r/| j                  t        |j
                  |j                  d|z         ||   }g }g }d}|j                  D ]w  }t        j                  dd dk\  rt        |t        j                        r4||   }	|	r'|j                  t        j                  |	|             n|j                  |       |dz  }y |rO| j                  t        |j
                  |j                  d|z         ||_        ||j                   xs g z   |_        y	y
)zEMake args into keyword args if function called full_name requires it.z(Manual check required) upgrading %s may require re-ordering the call arguments, but it was passed variable-length positional *args. The upgrade script cannot handle these automatically.r   Nr   r   )r#   r   r!   z%Added keywords to args of function %rTF)r\   rP   r0   rz   r   rw   r   r$   r%   r&   r'   r   r(   rb   r3   r   r"   )
rA   r   r   rP   	reorderednew_argsnew_keywordsr,   r#   keyword_args
             r   _maybe_add_arg_namesz&_PastaEditVisitor._maybe_add_arg_names  s*   --??%%		%Wdkk4??A DMM	N $I.ihlc #BQ6)jckk.J
n


ckkkE
F
//#
q 
T4;;<yH	J	$(;<r   c                    | j                  d||      }|syt        |      r3| j                  t        |j                  |j
                  d|xs |z         d}g }|j                  D ]  }|j                  }||v rd}||   Qt        |d|j                        }	t        |d|j
                        }
| j                  t        |	|
d|d|xs |       k||   |_        t        |d|j                        }	t        |d|j
                        }
| j                  t        |	|
d	|d
|d||          |j                  |       |j                  |        |r||_        |S )zARename keyword args if the function called full_name requires it.rQ   Fz(Manual check required) upgrading %s may require renaming or removing call arguments, but it was passed variable-length *args or **kwargs. The upgrade script cannot handle these automatically.Trw   r   zRemoved argument z for function zRenamed keyword argument for z from r   )r   r4   rz   r   rw   r   r"   r#   r   r   rb   )rA   r   r   r   renamed_keywordsmodifiedr   r3   argkeyrw   r   s              r   _maybe_modify_argsz$_PastaEditVisitor._maybe_modify_args  sj   001K1:DB %
ll7DKK? %	'( HL== %{{f	#	#F#+7Hdkk:&wdooF*
,,tVZ!9#4#467 )0'+7Hdkk:&wdooF*
,,tVZ$f.>v.FHI 

g
&G$'%* "dmOr   c                    | j                   d   |u sJ | j                  |j                        }|r|j                  d      d   }nxt	        |j                  t
        j                        r|j                  j                  }n=t	        |j                  t
        j                        r|j                  j                  }nd}| j                  |||       | j                  ||       | j                  |||       | j                  d||      }| j                   d   }|r>t        |      r3| j                  t         |j"                  |j$                  d|xs |z         |D ][  }g } ||||||      }| j'                  |       |s%||us*t(        j*                  j-                  |||       |}|| j                   d<   ] | j/                  |       y)zPHandle visiting a call node in the AST.

    Args:
      node: Current Node
    r
   NrV   z(Manual check required) upgrading %s may require modifying call arguments, but it was passed variable-length *args or **kwargs. The upgrade script cannot handle these automatically.)r^   r   r   r   r'   r   r   r   r   r   r   r   r   r   r6   rz   r   rw   r   r~   r   r   r   generic_visit)	rA   r   r   r   r   r   transformerr}   r   s	            r   
visit_Callz_PastaEditVisitor.visit_Call  s    ;;r?d""" ##DII.I__S!"%d	DIIsxx	(YY\\d	DIIs}}	-YY^^dd
 	  y$7dI.D)T2 //0G094AL [[_F	)$	/Wdkk4??A  '4	)	* $ dVT9dDAh
mmD	hd*%%fdH=B 	tr   c                 &   | j                   d   |u sJ | j                  |      }|r| j                   d   }| j                  ||       | j                  |||      ry| j	                  |||      ryd}t        | j                   |    t        j                        r.|dz  }t        | j                   |    t        j                        r.t        j                  | j                   |dz
            }| j                  |||       | j                  |       y)-Handle bare Attributes i.e. [tf.foo, tf.bar].r   r   Nr   r!   )r^   r   r   r   r   r'   r   r   r   dumpr   r   )rA   r   r   r   ir   s         r   visit_Attributez!_PastaEditVisitor.visit_AttributeB  s    ;;r?d"""##D)I{{2f dI.
 
		FD)	4		,	,VT9	E at{{A26	Q t{{A26::dkkAaC&12j
00y*Mtr   c                    g }d}t        | j                  di       }t        | j                  dd      }t        | j                  di       }|j                  D ]H  }|j                  j	                  d      }d}	t        t        t        d|dz                     D ]  }
|d   }t        dt        |
t        |                  D ]  }|d||   z   z  } |j                  |d      }|rt        |j                  |      rc|j                  |j                  t        |      d z   }|j                  }|sd|j                  vr|j                  }t        j                  ||	      }|j!                  |       d
}d
}	|j                  |j                  f}d}|j                  |g       D ]  }| j"                  d   |u sJ | j"                  d   }t%        j&                  |      }t        j(                  ||       |j*                  j-                  |j*                  j/                  |      |z   |       |dz  }t$        j0                  j2                  j                  |d      }|t4        j6                  }t4        j6                  |vr<t$        j0                  j2                  j9                  |d|t4        j6                  z          t$        j0                  j2                  j9                  |dt$        j0                  j2                  j                  |d             t$        j0                  j2                  j9                  |dt4        j6                         | j;                  t<        |j>                  |j@                  d|d|j                          |	s n |	r8|j!                  |       K |r| j"                  d   |u sJ | j"                  d   }t        jB                  |      }t        j(                  ||       t$        jD                  jG                  |||       | j;                  t<        |j>                  |j@                  dt%        jH                  |      dt%        jH                  |      d       | jK                  |       y)SHandle visiting an import node in the AST.

    Args:
      node: Current Node
    FrW   max_submodule_depthr!   inserts_after_importsr
   r   N)r   asnameTr   r   suffixprefixzAdding `z` after import of Changed import from r   )&r   r\   r   r   r   r   listrangeminlenr   r<   r   r   r   aliasrb   r^   r   parser   bodyinsertindexbase
formattingoslinesepsetrz   r   rw   r   Importr   r   r   r   )rA   r   new_aliasesimport_updatedrW   r   r   import_aliasall_import_componentsfound_updater   import_componentjr:   r   
new_asname	new_aliasfull_importinsert_offsetline_to_insertr   new_line_node
old_suffixr   s                           r   visit_Importz_PastaEditVisitor.visit_Import_  s    KNT224DbIN!$"7"79N"#%#D$9$9$;RA
 

 A)*//55c:lU1&9A&=>?@ :!03q#a%:!;<= 	=A
c$9!$<<
<
	=+//0@$G!%@1&3
 ''c"23456 	 "((
c):)::#((*II8J?	9% $((,*=*=>377RH 	2NRD(
((;;r?&++n5-


M4
0
++

kk%5}F
1
- zz,,00x@*JZZz)JJ!!%%dHj2::6MN **


#
#M8$)JJ$9$9$=$=dH$MO
**


#
#M8RZZ
H
,,DKKl//12+	24 
u:x <(CA)H [[_$$${{2fK(h	$'oo##FD(;
ll
T__::dUZZ134
 	tr   c                    |j                   s| j                  |       y|j                   }|j                  d      d   }t        | j                  di       }|j                  |d      }|s| j                  |       yg }g }|j                  D ]B  }|d|j                  }	t        |	|      r|j                  |       2|j                  |       D |s| j                  |       y| j                  d   |u sJ | j                  d   }
|j                  |t        |      d z   }t        j                  |||j                        }t        j                   ||       t"        j$                  j'                  |
||       d}|rt        j                  |||j                  |j(                  |j*                        }t        j                   ||       |
j,                  j/                  |
j,                  j1                  |      |       t"        j2                  j4                  j7                  |d	t"        j2                  j4                  j                  |d	             d
t#        j8                  |      z  }| j;                  t<        |j*                  |j(                  dt#        j8                  |      dt#        j8                  |      |d       | j                  |       y)XHandle visiting an import-from node in the AST.

    Args:
      node: Current Node
    Nr
   r   rW   r   r    )r   rw   r   z and %rr   r   )r9   r   r   r   r\   r   r   r   r<   rb   r^   r   r   r   
ImportFromr   r   r   r   r   r   rw   r   r   r   r   r   r   r   rz   r   )rA   r   from_importfrom_import_first_componentrW   r:   updated_aliasessame_aliasesr   full_module_namer   new_from_importupdated_nodeadditional_import_log	same_nodes                  r   visit_ImportFromz"_PastaEditVisitor.visit_ImportFrom  sk    ;;
++K #."3"3C"8";T224DbIN'++,GN
 OL

 -$/1B1BC	$%57I	JL)|,- 
;;r?d"""[[_F 	##C3456	7  >>/?DJJOLlD)	OO!!&$= ..lDJJ,0OODKKQi		4(kk**<8)Djj
X
**


#
#L(
;= (%**Y*??LLdkk4??	D		L	!		 ! 	tr   )rG   rH   rI   rJ   rX   rd   propertyrj   rm   ro   rq   ri   rz   r~   r   r   r   r   r   r   r   r   r   r   r   r   r   r  __classcell__re   s   @r   rZ   rZ      s    
 9 9 ; ; D D 8 8  >'"%,
*X D(T:x:`DFr   rZ   c                       e Zd ZdZy)AnalysisResulta6  This class represents an analysis result and how it should be logged.

  This class must provide the following fields:

  * `log_level`: The log level to which this detection should be logged
  * `log_message`: The message that should be logged for this detection

  For an example, see `VersionedTFImport`.
  NrG   rH   rI   rJ   r@   r   r   r  r  
  s    r   r  c                       e Zd ZdZy)APIAnalysisSpeca  This class defines how `AnalysisResult`s should be generated.

  It specifies how to map imports and symbols to `AnalysisResult`s.

  This class must provide the following fields:

  * `symbols_to_detect`: maps function names to `AnalysisResult`s
  * `imports_to_detect`: maps imports represented as (full module name, alias)
    tuples to `AnalysisResult`s
    notifications)

  For an example, see `TFAPIImportAnalysisSpec`.
  Nr  r@   r   r   r	  r	    s    r   r	  c                   J     e Zd ZdZ fdZed        Zd Zd Zd Z	d Z
 xZS )PastaAnalyzeVisitorzAST Visitor that looks for specific API usage without editing anything.

  This is used before any rewriting is done to detect if any symbols are used
  that require changing imports or disabling rewriting altogether.
  c                 X    t         t        |   t                      || _        g | _        y rN   )rc   r  rX   rL   _api_analysis_spec_results)rA   api_analysis_specre   s     r   rX   zPastaAnalyzeVisitor.__init__-  s$    	
t-ln=/DDMr   c                     | j                   S rN   )r  rE   s    r   resultszPastaAnalyzeVisitor.results2  s    ==r   c                 :    | j                   j                  |       y rN   )r  rb   )rA   analysis_results     r   
add_resultzPastaAnalyzeVisitor.add_result6  s    MM)r   c                 6   | j                  |      }|ru| j                  j                  j                  |d      }|rM| j	                  |       | j                  |j                  |j                  |j                  |j                         | j                  |       y)r   N)r   r  symbols_to_detectr   r  rz   	log_levelrw   r   log_messager   )rA   r   r   	detections       r   r   z#PastaAnalyzeVisitor.visit_Attribute9  s|    ##D)I));;??	4Pi		"doo!!	# 	tr   c                 d   |j                   D ]  }|j                  |j                  f}| j                  j                  j                  |d      }|sD| j                  |       | j                  |j                  |j                  |j                  |j                          | j                  |       y)r   N)r   r   r   r  imports_to_detectr   r  rz   r  rw   r   r  r   )rA   r   r   r   r  s        r   r   z PastaAnalyzeVisitor.visit_ImportF  s     

 	#!&&(;(;<k**%%cc+t&< 		"doo!!	#	# 	tr   c                    |j                   s| j                  |       y|j                   }|j                  D ]  }|d|j                  }||j                  f}| j
                  j                  j                  |d      }|sK| j                  |       | j                  |j                  |j                  |j                  |j                          | j                  |       y)r   Nr
   )r9   r   r   r   r   r  r  r   r  rz   r  rw   r   r  )rA   r   r   r   r   r   r  s          r   r  z$PastaAnalyzeVisitor.visit_ImportFromY  s     ;;
++K

 
#$/1B1BC%|':':;k**%%cc+t&< 		"doo!!	#
# 	tr   )rG   rH   rI   rJ   rX   r  r  r  r   r   r  r  r  s   @r   r  r  &  s5    
  *&r   r  c                   D    e Zd ZdZd Z	 ddZd Zd Zd Zd Z	d Z
d	 Zy
)ASTCodeUpgraderzFHandles upgrading a set of Python files using a given API change spec.c                 `    t        |t              st        dt        |      z        || _        y )Nz2Must pass APIChangeSpec to ASTCodeUpgrader, got %s)r'   r>   	TypeErrortyper\   r_   s     r   rX   zASTCodeUpgrader.__init__w  s1    o}5J?+, - -+Dr   c                 ^   t        |d      5 }t        j                  dd      5 }| j                  ||||      }ddd       ddd       |r)d   dk(  r!t	        j
                  j                         |S t        j                  j                  |       S # 1 sw Y   ^xY w# 1 sw Y   bxY w)a<  Process the given python file for incompatible changes.

    Args:
      in_filename: filename to parse
      out_filename: output file to write to
      no_change_to_outfile_on_error: not modify the output file on errors
    Returns:
      A tuple representing number of files processed, log of actions, errors
    rwF)deleteNr   )	opentempfileNamedTemporaryFileprocess_opened_filer   remover   shutilmove)rA   in_filenameout_filenameno_change_to_outfile_on_errorin_file	temp_filerets          r   process_filezASTCodeUpgrader.process_file}  s      
k3	 07##C60:C$$['<%.0c0 0 %Q1ii	 J kk)..,/J0 0 0 0s!   B#BB#B 	B##B,c                 D    d|d   |d   |d   |d   fz  }|r|dz   |z   S |S )Nz%d:%d: %s: %sr!   r   r   r   :r@   )rA   ri   r-  
log_strings       r   
format_logzASTCodeUpgrader.format_log  s>     CFCFCFCF#CCJ3++r   c                 R   	 t        j                  |      }| j                  j                  |      \  }}}t        | j                        }|j                  |       | j                  j                          ||j                  z   D cg c]  }| j                  |d       }}||j                  z   D 	cg c]  }	| j                  |	|       }
}	dt        j                  |      ||
fS # t        t        t        f$ r! dt        j                         z   g}dd|g fcY S w xY wc c}w c c}	w )zUpdates a file using pasta.zERROR: Failed to parse.
r   r   Nr!   )r   r   SyntaxError
ValueErrorr   	traceback
format_excr\   rC   rZ   rd   rF   ri   r7  ro   r   )rA   textr-  tri   preprocess_logspreprocess_errorsvisitorr}   errorrj   s              r   update_string_pastaz#ASTCodeUpgrader.update_string_pasta  s-   
++d
a
 -1,A,A,L,LQ,O)A) 5 56GMM!--/3B3:;;4? A3DOOC& AD A .#778: ooe[1 :F : ejjmT6))! Y/ (9+?+?+AABcC^A:s   C' D3D$'2DDc                 d    d}|d|d|dz  }|dz  }|dj                  |      dz   z  }|dz  }|S )NzQ--------------------------------------------------------------------------------
zProcessing file z
 outputting to 
zR--------------------------------------------------------------------------------

)r   )rA   ri   r-  r.  r=  s        r   _format_logzASTCodeUpgrader._format_log  sO    D9EG GDDDIIcNT!!DDKr   c                     |j                         }| j                  dj                  |      |      \  }}}}	|r|r|j                  |       || j	                  |||      |	fS )a  Process the given python file for incompatible changes.

    This function is split out to facilitate StringIO testing from
    tf_upgrade_test.py.

    Args:
      in_filename: filename to parse
      in_file: opened file (or StringIO)
      out_filename: output file to write to
      out_file: opened file (or StringIO)
    Returns:
      A tuple representing number of files processed, log of actions, errors
    r   )	readlinesrC  r   writerF  )
rA   r-  r0  r.  out_filelinesprocessed_filenew_file_contentri   process_errorss
             r   r)  z#ASTCodeUpgrader.process_opened_file  sn     E  = :N$c> Nnn%&S+|< r   c           	      N   ||k(  r| j                  |      S |rBt        j                  j                  |      r#t	        d|z         t        j                  d       t        j                  j                  t        j                  j                  |            }t        j                  j                  t        j                  j                  |            }||k(  r&t	        d|d|       t        j                  d       g }g }t        j                  |      D ]<  \  }}	}
|
D cg c]  }|j                  d      s| }}|
D cg c]  }|j                  d      r| }}|D ]s  }t        j                  j                  ||      }t        j                  j                  |t        j                  j                  ||            }|j                  ||f       u |s|D ]s  }t        j                  j                  ||      }t        j                  j                  |t        j                  j                  ||            }|j                  ||f       u ? d}i }d}|dz  }|d	|z  z  }|dz  }|D ]0  \  }}t        j                  j                  |      }t        j                  j                  |      st        j                   |       t        j                  j#                  |      rt        j$                  |      }t        j                  j                  |t        j                  j                  ||            }||f|v rt        j&                  ||       n!|d
|d|z  }t        j&                  ||       |dz  }| j)                  ||      \  }	}}|||<   ||z  }3 |D ]n  \  }}t        j                  j                  |      }t        j                  j                  |      st        j                   |       t+        j,                  ||       p |||fS c c}w c c}w )a  Processes upgrades on an entire tree of python files in place.

    Note that only Python files. If you have custom code in other languages,
    you will need to manually upgrade those.

    Args:
      root_directory: Directory to walk and process.
      output_root_directory: Directory to use as base.
      copy_other_files: Copy files that are not touched by this converter.

    Returns:
      A tuple of files processed, the report string for all files, and a dict
        mapping filenames to errors encountered in that file.
    z+Output directory %r must not already exist.r!   zOutput directory z same as input directory .pyr   r   Q================================================================================
Input tree: %r
zCopying symlink z without modifying its target )process_tree_inplacer   pathexistsru   r%   exitr   normpathwalkendswithr   relpathrb   dirnameisdirmakedirsislinkreadlinksymlinkr3  r+  r   )rA   root_directoryoutput_root_directorycopy_other_files	norm_rootnorm_outputfiles_to_processfiles_to_copydir_namer   	file_listfpy_files
copy_filesfilenamefullpathfullpath_output
file_counttree_errorsreport
input_pathoutput_pathoutput_directorylink_targetlink_target_outputl_reportl_errorss                              r   process_treezASTCodeUpgrader.process_tree  s   " .&&~66 0E!F9"$ %	hhqk bgg..~>?I''-- 0 01F GHKK24 5	hhqk M"$''."9 <!Y&<!**U*;!<h<(B!

50AABjB =(77<<(3'',,'<')wwx7E(GH 	? ;<= 
" 	<HWW\\(H5(GGLL)>)+-5~*GH/ 

/:
;	<<" JKF
F
 >11F
F#3 
K5WW]]+,
$%	
	#kk*-WW\\!277??;#OQ+,0@@
**'
5
+' '&
**[+
.Aoj"//
KHa8 (k*f+. $1 +
K5WW]]+,
$%kk*k*	+
 v{**g =Bs   #P:PP"P"c                    g }t        j                  |      D ]J  \  }}}|D cg c]4  }|j                  d      st         j                  j	                  ||      6 }}||z  }L d}i }	d}
|
dz  }
|
d|z  z  }
|
dz  }
|D ]O  }t         j                  j                  |      r	|
d|z  z  }
+|dz  }| j                  ||      \  }}}||	|<   |
|z  }
Q ||
|	fS c c}w )z-Process a directory of python files in place.rP  r   r   rQ  rR  zSkipping symlink %s.
r!   )r   rX  rY  rT  r   r^  r3  )rA   ra  rf  rh  r   ri  rj  rk  rp  rq  rr  rT  rx  ry  s                 r   rS  z$ASTCodeUpgrader.process_tree_inplace4  s   "$''."9 #!Y-6()!**U:K"'',,x
#h  ("	# JKF
F
 >11F
F  		*T11Aoj"//d;a8"k$f v{**+s
   C"CN)F)rG   rH   rI   rJ   rX   r3  r7  rC  rF  r)  rz  rS  r@   r   r   r  r  t  s4    N, 278*,2Z+x+r   r  rN   )!rJ   r   collectionsr   rer+  r%   r'  r;  r   compile	FIND_OPENFIND_STRING_CHARSr   r   r   
namedtupler   r   r   r-   r0   r4   r6   r<   r>   rL   NodeVisitorrZ   r  r	  r  r  r@   r   r   <module>r     s    L 
  	 	  
    BJJ~&	BJJx(  
 &{%%Z!457 &SXXZ .$N00H " 	  	F= [ [|	 	  K+ K\Y+ Y+r   