+
    VBi<              	       
   ^ RI t ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RIHt ^RI	H
t
 ^RIHt ^RIHtHtHt ^RIHtHt ^RI	Ht ^RIHt  ! R	 R
]4      tR t ! R R]P0                  4      t ! R R]4      t]! ]P6                  ! ]P8                  ! RRR4      4      P8                  R4      t]! ]P6                  ! ]P8                  ! RRR4      4      P8                  R4      tR t ! R R]4      t R t!RR lt"RR lt#R t$R# )    N)partial)Errors)
CodeWriter)TreeFragmentstrip_common_indentStringParseContext)TreeVisitorVisitorTransform)TreePath)	PostParsec                   8   a a ] tR t^t oV 3R ltR tRtVtV ;t# )NodeTypeWriterc                @   < \         SV `  4        ^ V n        . V n        R# )r   N)super__init___indentsresultself	__class__s   &5/usr/lib/python3.14/site-packages/Cython/TestUtils.pyr   NodeTypeWriter.__init__   s        c                   V P                   '       g   R pM8V P                   R,          pV^,          e   RVR,          ,          pM	V^,          pV P                  P                  RV P                  ,          V: RVP                  P
                  : 2,           4       V ;P                  ^,          un        V P                  V4       V ;P                  ^,          un        R# )z(root)Nz%s[%d]:      Nz  z: )access_pathr   appendr   r   __name__visitchildren)r   nodenametips   &&  r   
visit_NodeNodeTypeWriter.visit_Node   s    D""2&C1v!#c(*1v4$--/'+T^^-D-DEF 	G4 r   )r   r   )	r    
__module____qualname____firstlineno__r   r%   __static_attributes____classdictcell____classcell__r   __classdict__s   @@r   r   r      s     
 r   r   c                    \        4       pVP                  V 4       RP                  R.VP                  ,           R.,           4      # )zReturns a string representing the tree by class names.
There's a leading and trailing whitespace so that it can be
compared by simple string comparison while still making test
cases look ok.
 )r   visitjoinr   )rootws   & r   	treetypesr6   )   s7    
 	AGGDM99bTAHH_t+,,r   c                   l   a  ] tR t^3t o R tR tR tR tR tR t	R t
RR	 ltR
 t]3R ltR tRtV tR# )
CythonTestc                0    \         P                  ! 4        R # Nr   init_threadr   s   &r   setUpCythonTest.setUp5       r   c                0    \         P                  ! 4        R # r:   r;   r=   s   &r   tearDownCythonTest.tearDown8   r@   r   c           
        \        V\        4      '       g   VP                  R4      p\        V\        4      '       g   VP                  R4      p\        \	        W4      4       F#  w  pw  rEV P                  WERW4V3,          4       K%  	  V P                  \        V4      \        V4      RRP                  V4      : RRP                  V4      : 24       R# )zHChecks that the given strings or lists of strings are equal line by liner0   zLine %d:
Exp: %s
Got: %sUnmatched lines. Got:

Expected:
N)
isinstancelistsplit	enumeratezipassertEquallenr3   )r   expectedr   idxexpected_lineresult_lines   &&&   r   assertLinesCythonTest.assertLines;   s    (D))~~d+H&$''\\$'F1:3x;P1Q-C--]9SQ\<]]_ 2R 	XFGKyyQYGZ\`\e\efl\mn	pr   c                d    \        4       pVP                  V4       VP                  P                  # r:   )r   writer   lines)r   treewriters   && r   codeToLinesCythonTest.codeToLinesG   s%    T}}"""r   c                B    R P                  V P                  V4      4      # )r0   )r3   rY   )r   rW   s   &&r   codeToStringCythonTest.codeToStringL   s    yy))$/00r   c           	     J   V P                  V4      p\        VP                  R 4      4      p\        \	        W44      4       F#  w  pw  rgV P                  WvRWVV3,          4       K%  	  V P                  \        V4      \        V4      RR P                  V4      : RV: 24       R# )r0   zLine %d:
Got: %s
Exp: %srE   rF   N)rY   r   rI   rJ   rK   rL   rM   r3   )r   rN   result_treeresult_linesexpected_linesrO   linerP   s   &&&     r   
assertCodeCythonTest.assertCodeO   s    ''4,X^^D-AB*3C4U*V&C&$]9S<VVX +W 	\*C,?GKyyQ]G^`hi	kr   c                b    V P                  \        P                  ! W!4      R RV,          4       R # )Nz"Path '%s' not found in result tree)assertNotEqualr   
find_first)r   pathr_   s   &&&r   assertNodeExistsCythonTest.assertNodeExistsZ   s(    H//BD@4G	Ir   Nc                    Vf   / pVf   . pV P                  4       pVP                  R4      '       d   V\        R4      R pVP                  RR4      p\	        WW#R7      # )zNSimply create a tree fragment using the name of the test-case in parse errors.Nz	__main__.._pipeline)id
startswithrM   replacer   )r   codepxdsro   r#   s   &&&& r   fragmentCythonTest.fragment^   s`    <DHwwy??;''K()*D||C%D@@r   c                    \        V4      # r:   )r6   )r   r4   s   &&r   r6   CythonTest.treetypesj   s    r   c                     V! 4        V P                  RV,          4       R#   T d'   pT P                  \        Y24      4       Tu Rp?# Rp?ii ; i)zCalls "func" and fails if it doesn't raise the right exception
(any exception by default). Also returns the exception in question.
z Expected an exception of type %rN)fail
assertTruerG   )r   funcexc_typees   &&& r   should_failCythonTest.should_failm   sD    	FII88CD 	OOJq34H	s   # AAAAc                x     V! 4       #   \          d&   pT P                  \        T4      4        Rp?R# Rp?ii ; i)zCalls func and succeeds if and only if no exception is raised
(i.e. converts exception raising into a failed testcase). Returns
the return value of func.N)	Exceptionrz   str)r   r|   excs   && r   should_not_failCythonTest.should_not_failx   s1    	 6M 	 IIc#h	 s   	 949 )NN)r    r'   r(   r)   r>   rB   rR   rY   r\   rc   ri   ru   r6   r   r   r   r*   r+   r.   s   @r   r8   r8   3   sJ     
p#
1	kI
A *3 	   r   r8   c                   .   a  ] tR t^t o RtRR ltRtV tR# )TransformTesta  
Utility base class for transform unit tests. It is based around constructing
test trees (either explicitly or by parsing a Cython code string); running
the transform, serialize it using a customized Cython serializer (with
special markup for nodes that cannot be represented in Cython),
and do a string-comparison line-by-line of the result.

To create a test case:
 - Call run_pipeline. The pipeline should at least contain the transform you
   are testing; pyx should be either a string (passed to the parser to
   create a post-parse tree) or a node representing input to pipeline.
   The result will be a transformed result.

 - Check that the tree is correct. If wanted, assertCode can be used, which
   takes a code string as expected, and a ModuleNode in result_tree
   (it serializes the ModuleNode to a string and compares line-by-line).

All code strings are first stripped for whitespace lines and then common
indentation.

Plans: One could have a pxd dictionary parameter to run_pipeline.
Nc                j    Vf   / pV P                  W#4      P                  pV F  pV! V4      pK  	  V# r:   )ru   r4   )r   ro   pyxrt   rW   Ts   &&&&  r   run_pipelineTransformTest.run_pipeline   s8    <D}}S',,AT7D r   r   r:   )r    r'   r(   r)   __doc__r   r*   r+   r   s   @r   r   r      s     . r   r   z\s+r1   zz
        /[*] (
            (?: [^*\n] | [*][^/] )*
            [\n]
            (?: [^*] | [*][^/] )*
        ) [*]/
    z\s\s+z
    (?:
        <pre class=["'][^"']*cython\s+line[^"']*["']\s*>
        (?:[^<]|<(?!/pre))+
        </pre>
    )|(?:
        <style[^>]*>
        (?:[^<]|<(?!/style))+
        </style>
    )
    c                    R ;rV P                  R4      '       d3   \        P                  ! RV R,          ^R7      w  rV P                  4       p V P                  R4      '       da   V R,          P                  4       p V P                  R4      '       d3   \        P                  ! RV R,          ^R7      w  r V P                  4       p WV 3# )N/z(?<!\\)/r   NN)maxsplit:)rq   rerI   strip)patternstartends   &  r   _parse_patternr      s    E#+wr{QG--/#"+##%c""88KqILCmmoGwr   c                   b   a a ] tR t^t oV 3R ltR tR tR tR t]	P                  tRtVtV ;t# )TreeAssertVisitorc                N   < \         SV `  4        R V n        . V n        . V n        R # r:   )r   r   _module_pos_c_patterns_c_antipatternsr   s   &r   r   TreeAssertVisitor.__init__   s&    !r   c                |   a aaaaa S P                   S P                  uooR  oVV 3R loVVVVV 3R loVVV3R lpV# )c           	      `    \         P                  ! T R V: RV'       d   RMR: RV: 24       R# )z	Pattern 'z' waszwas notz
 found in N)r   error)posr   found	file_paths   &&&&r   rz   7TreeAssertVisitor.create_c_file_validator.<locals>.fail   s%    LLI- r   c                 H  < V'       dH   \         P                  ! W!4      pV'       d   WP                  4       R  pMS! SP                  VRV R7       V'       dJ   \         P                  ! W14      pV'       d   VR VP	                  4        pV# S! SP                  VRV R7       V# )NFr   r   )r   searchr   r   r   )r   contentr   r   rI   rz   r   s   &&&& r   extract_sectionBTreeAssertVisitor.create_c_file_validator.<locals>.extract_section   s    		%1%iikl3G))5S		#/%nu{{}5G N ))3eyQNr   c                 X  < S
 FN  p\        V4      w  r4pS! WW44      p\        P                  ! W%4      '       d   K8  S	! SP                  VR V R7       KP  	  S FN  p\        V4      w  r4pS! WW44      p\        P                  ! We4      '       g   K8  S	! SP                  VRV R7       KP  	  R# )Fr   TN)r   r   r   r   )r   r   r   r   r   sectionantipatternantipatternsr   rz   patternsr   s   &&     r   validate_file_contentHTreeAssertVisitor.create_c_file_validator.<locals>.validate_file_content   s    #&4W&=#G))eIyy22))7%9U $  ,*8*E'K))eI99[22));diX  ,r   c                    < V P                   pS'       g   S'       g   V # \        VR R7      ;_uu_ 4       pVP                  4       pRRR4       \        X4      pS! W4       R#   + '       g   i     L%; i)utf8)encodingN)c_fileopenread_strip_c_comments)r   r   fr   r   r   r   s   &   r   validate_c_fileBTreeAssertVisitor.create_c_file_validator.<locals>.validate_c_file   sP    ]]Ffv..!&&( /'0G!&2 /.s   A##A3	)r   r   )r   r   r   r   rz   r   r   s   f @@@@@r   create_c_file_validator)TreeAssertVisitor.create_c_file_validator   s>    !%!1!143G3G,			Y 	Y		3 r   c                   VP                   pR V9   dS   VR ,           FE  p\        P                  ! W4      e   K  \        P                  ! VP
                  RV,          4       KG  	  RV9   dU   VR,           FG  p\        P                  ! W4      pVf   K  \        P                  ! VP
                  RV,          4       KI  	  RV9   d#   V P                  P                  VR,          4       RV9   d#   V P                  P                  VR,          4       RV9   dq   VR,          pVeb   ^RI	H
p V! 4       pV! VP                  4      '       * pWX8w  d6   V! VP                  4       \        P                  ! VP
                  R	4       R# R# R# R# )
test_assert_path_existsNz+Expected path '%s' not found in result treetest_fail_if_path_existsz)Unexpected path '%s' found in result treetest_assert_c_code_hastest_fail_if_c_code_has"test_body_needs_exception_handling)HasNoExceptionHandlingVisitorz,Node had unexpected exception handling value)
directivesr   rg   r   r   r   r   extendr   Compiler.ParseTreeTransformsr   body)	r   r"   r   rh   
first_nodevaluer   visitorr   s	   &&       r   _check_directives#TreeAssertVisitor._check_directives  sS   __
$
2"#<==&&t2:LLELN >
 &3"#=>>%00<
)LL"CdJL ? $z1##J/G$HI$
2  ''
3L(MN/:=CDE W79$TYY//?DII&LLF #	 ! >r   c                l    VP                   V n        V P                  V4       V P                  V4       V# r:   )r   r   r   r!   r   r"   s   &&r   visit_ModuleNode"TreeAssertVisitor.visit_ModuleNode-  s/    88t$4 r   c                J    V P                  V4       V P                  V4       V# r:   )r   r!   r   s   &&r   visit_CompilerDirectivesNode.TreeAssertVisitor.visit_CompilerDirectivesNode3  s#    t$4 r   )r   r   r   )r    r'   r(   r)   r   r   r   r   r   r
   recurse_to_childrenr%   r*   r+   r,   r-   s   @@r   r   r      s/     "3j@
 "55JJr   r   c           
      B   R \         P                  .R\         P                  \        P                  P	                  VR4      .R\         P                  \        P                  P	                  VR4      ./pVf   \
        P                  ! 4       p. RrT\        V R4      ;_uu_ 4       p V EF  pVR,          R8X  Ed   VP                  4       P                  R	4      P                  4       P                  R
4      P                  R\        P                  P                  4      p\        P                  P	                  W4      p	\        P                  P                  \        P                  P                  V	4      4      '       g4   \        P                  ! \        P                  P                  V	4      4       Ve   TRrZV
P                  4        \        V	R4      pEK1  Ve   VP!                  V4       EKI  VP                  4       '       g   EKb  VP#                  4       P%                  R	4      '       d   EK  VP                  4       R9  g   EK  \&        P(                  ! VP                  R
4      4      pV'       g   EK  V^ ,          VR,          r VP+                  W<,          V,           4       EK  	  Ve   VP                  4        RRR4       Y3#   \,         d    TP+                  T4        EKF  i ; i  Te   TP                  4        i i ; i  + '       g   i     Y3# ; i)PYTHONCYTHONz	cython.py	CYTHONIZEzcythonize.pyNrb:N   Ns   #####   #r   r   wbr   )s   """s   ''')sys
executableosrh   r3   tempfilemkdtempr   r   decoderr   sepexistsdirnamemakedirscloserU   lstriprq   shlexrI   r   KeyError)	tree_fileworkdircython_rootprogramsheadercur_filer   rb   filenamerh   to_closecommandprogargss   &&&           r   unpack_source_treer   ;  s9   3>>"3>>277<<[#IJcnnbggll;&OPH ""$4H	i		!	!8x'#zz|11$7==?FFvNVVWZ\^\c\c\g\ghH77<<:D77>>"''//$*?@@BGGOOD$9:+-5t( (#D$/H)NN4(ZZ\\$++-*B*B4*H*Hzz|+;;"'++dkk&.A"B&%,QZd3"MM(.*=>' . # 5 
6 ?  ( 3"MM'223 #  $3 
	6 ?sa   $L&EK2
"K22K2
,K27K2K*K2/LK/	*K2.K/	/K22L		LL	c                   \        V\        4      '       d   RpRpRpMRpRpRpVf   TpV'       d   \        P                  ! V4      p\	        WW5R7      ;_uu_ 4       pVP                  V4       RRR4       R#   + '       g   i     R# ; i)zWrite some content (text or bytes) to the file
at `file_path` without translating `'\n'` into `os.linesep`.

The default encoding is `'utf-8'`.
r   Nr5   r0   zutf-8)moder   newline)rG   bytestextwrapdedentr   rU   )r   r   r  r   r   r   default_encodingr   s   &&&&    r   
write_filer  c  s|     '5!!  "#//'*	iX	G	G1	 
H	G	G	Gs   A99B
	c                    \        WW4R7        \        P                  P                  V4      pVe%   V\        P                  P                  V 4      8  d   \        WW4R7       K7  R#   \         d    Rp LHi ; i)z
Write `content` to the file `file_path` without translating `'\n'`
into `os.linesep` and make sure it is newer than the file `newer_than`.

The default encoding is `'utf-8'` (same as for `write_file`).
)r  r   N)r  r   rh   getmtimeOSError)r   
newer_thanr   r  r   
other_times   &&&&& r   write_newer_filer    sk     y&DWW%%j1

 

bgg.>.>y.I I9fH !J	  
s   A' 'A76A7c                d   \        R4      p \        P                  ! 4       ;_uu_ 4       p\        V \	        V4      .R7      pVP                  4       pRRR4       X'       d
   V^ ,          hX#   + '       g   i     L#; i  \        P                   d   p\        TP                  4      hRp?ii ; i)z
Compiles code far enough to get errors from the parser and post-parse stage.

Is useful for checking for syntax errors, however it doesn't generate runable
code.
testrn   N)	r   r   local_errorsr   r   
substituteCompileErrorSyntaxErrormessage_only)rs   contexterrorsr   r~   s   &    r   py_parse_coder    s     !(G	*  ""f!$)G2D1EFF&&(F # )OM #"  *!..))*s4   B  (A-B  "
B  -A=	8B   B/B**B/)FN)%r   r   unittestr   r   r   r  	functoolsr   Compilerr   r   Compiler.TreeFragmentr   r   r   Compiler.Visitorr	   r
   r   r   r   r   r6   TestCaser8   r   compilesubr   _strip_cython_code_from_htmlr   r   r   r  r  r  r   r   r   <module>r     s    	 	   
     " X X ;  3[ .-L "" L ^J L BJJFF62  	 #r   'rzzFF8R 
 
	( #r  
j6( j6Z%P<I&*r   