
    oi4                        d Z ddlZddlmc mZ ddlZddl	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ZddlmZ ddlmZ  e
j4                  e      Zd Zd	 Zej>                  jA                  d
      rd Z!nd Z" ejF                  d      d        Z$ejF                  d        Z% G d d      Z&d Z'de(de)de(fdZ*de(de)de(fdZ+de,de,de-e(   de,fdZ.dede(fdZ/y) zLangSmith Pytest hooks.    N)defaultdict)Lock)Any)utils)testc                     	 | j                  dd      }|j                  dddd       y	# t        $ r t        j	                  d       Y y	w xY w)
zaSet a boolean flag for LangSmith output.

    Skip if --langsmith-output is already defined.
    	langsmith	LangSmith--langsmith-output
store_trueFz'Use LangSmith output (requires 'rich').)actiondefaulthelpzCLangSmith output flag cannot be added because it's already defined.N)getgroup	addoption
ValueErrorloggerwarning)parsergroups     _/home/jang/Projects/ai-researcher/.venv/lib/python3.12/site-packages/langsmith/pytest_plugin.pypytest_addoptionr      sT    

[9 :	 	 	
  
Q	

s   '* A
Ac                      t         fddD              rNt         fddD              s j                  dd       t         fddD              s j                  dd	       y
y
y
)zHandle output arguments.c              3   &   K   | ]  }|v  
 y wN ).0optargss     r   	<genexpr>z&_handle_output_args.<locals>.<genexpr>+   s     
933$;
9   )r   c              3   &   K   | ]  }|v  
 y wr   r   r   ar   s     r   r    z&_handle_output_args.<locals>.<genexpr>-   s     .19.r!   )-qqr   r%   c              3   &   K   | ]  }|v  
 y wr   r   r#   s     r   r    z&_handle_output_args.<locals>.<genexpr>0   s     =19=r!   )-sz--capture=nor'   N)anyinsertr   s   `r   _handle_output_argsr+   )   sU    

9"8
99.g..KK5!=&<==KK4  > :    z7.c                     t        |       y)zCCall immediately after command line options are parsed (pytest v7).Nr+   )configr   s     r   pytest_cmdline_preparser0   6   
    D!r,   c                     t        |        y)zHandle args in pytest v8+.Nr.   r*   s    r   pytest_load_initial_conftestsr3   <   r1   r,   T)hookwrapperc              #     K   | j                  d      }|r|r|j                  ni }t        | dd      }d|vr|	 |j                  d      }|i |d|i}| j                  } t        d	i ||      | _        |d| j                  vr|| j                  d<   |d| j                  j                  vrw t        | j                        | j                  j                  dz   | j                  j                  | j                  j                  | j                  j                        | _	        d y# t        j
                  $ r Y w xY ww)
zEApply LangSmith tracking to tests marked with @pytest.mark.langsmith.r	   _requestNexperiment_metadatalangsmith_experiment_metadatarequest)r9   )argnamesinitialnamesnames_closurename2fixturedefsr   )get_closest_markerkwargsgetattrgetfixturevaluepytestFixtureLookupErrorobjls_testfuncargs_fixtureinfor:   typer;   r<   r=   )itemmarkerr?   request_objr7   original_funcs         r   pytest_runtest_callrM   A   sM     $$[1F #)b dJ5 .;3J&1&A&A3'# '2SS(=?RSF $7$V$]3"y'E'2DMM)$"y8I8I8R8R'R 7T%6%6 7**33lB!..;;"//==!%!2!2!C!C	!D 
 ,, s)   8ED- CE-E EEEc                 (    |j                  d      ryy)z7Remove the short test-status character outputs ("./F").r   ) rO   rO   N)	getoption)reportr/   s     r   pytest_report_teststatusrR   e   s    
 ,- .r,   c                   L    e Zd ZdZd Zd Zd Zd Zd Zd Z	de
fd	Zd
 Zd Zy)LangSmithPluginz'Plugin for rendering LangSmith results.c                 d   ddl m} ddlm} t	        t
              | _        i | _        i | _        t               | _
         |       | _         || j                         | j                  d      | _        | j                  j                          | j                  j                  j                  d       y)zInitialize.r   )Console)Live
   )consolerefresh_per_secondzCollecting tests...N)rich.consolerV   	rich.liverW   r   listtest_suitestest_suite_urlsprocess_statusr   status_lockrY   generate_tableslivestartprint)selfrV   rW   s      r   __init__zLangSmithPlugin.__init__q   s    ("&t,! 6y  "DLLR
	 					 56r,   c                     t               | _        |j                  D ]'  }| j                  j                  |j                         ) y)zHCall after collection phase is completed and session.items is populated.N)setcollected_nodeidsitemsaddnodeid)rf   sessionrI   s      r   pytest_collection_finishz(LangSmithPlugin.pytest_collection_finish   s7    !$MM 	4D""&&t{{3	4r,   c                 @    | j                   |   j                  |       y)z&Group a test case with its test suite.N)r^   append)rf   
test_suite
process_ids      r   add_process_to_test_suitez)LangSmithPlugin.add_process_to_test_suite   s    $++J7r,   c                 l   | j                   s%| j                  j                  j                  d       | j                  5  | j                   j                  |i       }t        ||g d      | j                   |<   ddd       | j                  j                  | j                                y# 1 sw Y   3xY w)zUpdate test results.zRunning tests...)feedbackinputsreference_outputsoutputs)unpackN)	r`   rc   rY   re   ra   get_merge_statusesupdaterb   )rf   rs   statuscurrent_statuss       r   update_process_statusz%LangSmithPlugin.update_process_status   s     ""II##$67 	!0044ZDN.=M/D
+	 			--/0	 	s   :B**B3c                 ,    | j                  |ddi       y)z/Initialize live display when first test starts.r~   runningN)r   )rf   rm   s     r   pytest_runtest_logstartz'LangSmithPlugin.pytest_runtest_logstart   s    ""6Hi+@Ar,   c                     ddl m} g }| j                  D ]$  }| j                  |      }|j	                  |       &  || }|S )u   Generate a collection of tables—one per suite.

        Returns a 'Group' object so it can be rendered simultaneously by Rich Live.
        r   )Group)r[   r   r^   _generate_tablerq   )rf   r   tables
suite_nametabler   s         r   rb   zLangSmithPlugin.generate_tables   sM    
 	'** 	!J((4EMM% 	! vr,   r   c                    ddl m} | j                  |   }d| d| j                  |    d} ||d      }|j	                  d       |j	                  d	       |j	                  d
       |j	                  d       |j	                  d       |j	                  d       |j	                  d       t        d      }t        d      }t        j                         }g }	t        t              }
|D ci c]  }|| j                  |    }}|j                         D ]  \  }}|j                  d|      |j                  d|      z
  }|	j                  |       |j                  di       j                         D ]5  \  }}t        |t        t        t         f      s"|
|   j                  |       7 t#        t        |dd      |      }t#        t        |j                  dd            |      } t%        d |j'                         D              }t%        d |j'                         D              }||z   r|||z   z  }|dk(  rdnd}d| d|dd| d}nd }|	rt%        |	      t        |	      z  dd}nd!}|
r'd"j)                  d# |
j                         D              }nd$}t#        |t        |            }| j*                  j,                  ||z   z
  d%z  t#        d&      |j                         D ]I  \  }}d'ddd(d)j                  |j                  dd      d*      }|j                  d|      |j                  d|      z
  }d"j)                  fd+|j                  di       j                         D              }t/        |j                  d,i             }t/        |j                  d-i             }t/        |j                  d.i             }|j1                  t3        t5        |      /      t7        |/      t7        |/      t7        |/       d0 d| d|j                  dd       d| d||dd       L |j1                  d1d1d1d1d1d1d1       |j1                  d2d1d1d1|||       |S c c}w )3zGenerate results table.r   )TablezTest Suite: [bold]z$[/bold]
LangSmith URL: [bright_cyan]z[/bright_cyan]left)titletitle_justifyTestInputszRef outputsOutputsStatusFeedbackDurationr~   durationend_time
start_timerv   z.2fsqueuedc              3   D   K   | ]  }|j                  d       dk(    yw)r~   passedNr{   r   r   s     r   r    z2LangSmithPlugin._generate_table.<locals>.<genexpr>        X1155?h6X    c              3   D   K   | ]  }|j                  d       dk(    yw)r~   failedNr   r   s     r   r    z2LangSmithPlugin._generate_table.<locals>.<genexpr>   r   r      greenred[]z.0%z[/z
Passed: --z--s
c              3   Z   K   | ]#  \  }}| d t        |      t        |      z    % yw): N)sumlen)r   kvs      r   r    z2LangSmithPlugin._generate_table.<locals>.<genexpr>   s1      +.2a1#RAQ()+s   )+z--      yellowcyan)r   r   r   skippedwhitec              3   ~   K   | ]4  \  }}t        |        dt        |t              rt        |      n|  6 yw)max_lenr   N)_abbreviate
isinstanceboolint)r   r   r   max_dynamic_col_widths      r   r    z2LangSmithPlugin._generate_table.<locals>.<genexpr>   sD      !Aq q*?@AjYZ\`NaCFghCij!s   :=rw   rx   ry   r   NrO   z[bold]Averages[/bold])
rich.tabler   r^   r_   
add_columnr   timer   r]   r`   rk   r{   rq   r   floatr   r   maxr   valuesjoinrY   width_dumps_with_fallbackadd_row_abbreviate_test_namestrr   )rf   r   r   process_idsr   r   
max_statusmax_durationnow	durationsnumeric_feedbackspidsuite_statusesr~   r   r   r   passed_countfailed_countratecoloraggregate_statusaggregate_durationaggregate_feedbackstatus_colorrv   rw   rx   ry   r   s                                @r   r   zLangSmithPlugin._generate_table   s   $&&z2&zl 3!11*=>nPE8 "'#"$$ ]
:iik	'-CNOC#t22377OO)//1 	NKCzz*c2VZZc5RRHX&

:r288: 31a%d!34%a(//23 shs^1#56ELSHh!?@*MJ	N X@U@U@WXXX@U@U@WXX ,&<,#>?D#qyGeE!"5'4*BugQ?+$'	NS^$CC#H!J!&!% +6G6M6M6O+ " "&<-?)@A!%!3!3zL7P!QVW W #$91 =)//1 	KC#!!	
 c&**Xx0':  zz*c2VZZc5RRHyy !"JJz26<<>! H *&**Xr*BCF 4

.3! +6::i+DEGMM%c#h8MNF,AB-7LMG-BC**+ L>6::h#A"B"\NRSTC."
%	> 	b"b"b"b1#	
 ] Ps   -Q(c                 r    d|j                   _        |j                  j                  d      }|r	d |_        yy)z9Disable warning reporting and show no warnings in output.Fzwarnings-pluginc                       y r   r   )r   r?   s     r   <lambda>z2LangSmithPlugin.pytest_configure.<locals>.<lambda>  s    r,   N)optionshowwarningspluginmanager
get_pluginwarning_summary)rf   r/   reporters      r   pytest_configurez LangSmithPlugin.pytest_configure  s9     &+" ''223DE'CH$ r,   c                     | j                   j                          | j                   j                  j                  d       y)z3Stop Rich Live rendering at the end of the session.z
Finishing up...N)rc   stoprY   re   )rf   rn   s     r   pytest_sessionfinishz$LangSmithPlugin.pytest_sessionfinish   s)    				 34r,   N)__name__
__module____qualname____doc__rg   ro   rt   r   r   rb   r   r   r   r   r   r,   r   rT   rT   n   s>    17$481Bf# fPD5r,   rT   c                    | j                  dd       | j                  d      rt        j                  j	                  d      sd}t        |      t        j                  j                  d      rd}t        |      t        j                         rd}t        |      | j                  j                  t               d	       d
| j                  _        yy)z Register the 'langsmith' marker.markersz/langsmith: mark test to be tracked in LangSmithr   richzoMust have 'rich' installed to use --langsmith-output. Please install with: `pip install -U 'langsmith[pytest]'`PYTEST_XDIST_TESTRUNUIDzq--langsmith-output not supported with pytest-xdist. Please remove the '--langsmith-output' option or '-n' option.z--langsmith-output not supported when env varLANGSMITH_TEST_TRACKING='false'. Please remove the'--langsmith-output' option or enable test tracking.langsmith_output_pluginFN)addinivalue_linerP   	importlibutil	find_specr   osenvironr{   ls_utilstest_tracking_is_disabledr   registerrT   r   r   )r/   msgs     r   r   r   &  s    
D ,-~~''/L  S/!::>>34P  S/!--/+  S/!%%o&79RS%*"/ .r,   xr   returnc                 8    t        |       |kD  r| d |dz
   dz   S | S )N   ...)r   )r   r   s     r   r   r   E  s)    
1v7Q;%''r,   	test_namec                     t        |       |kD  rQ| j                  d      \  }}t        d|z         |kD  rd||dz
   d  z   S |t        d|z         z
  }d|| d  z   dz   |z   S | S )Nz::z.py::r   r   z...::)r   split)r   r   filer   file_lens        r   r   r   L  s    
9~__T*
dw~(4'A+ 0111S400tXIJ''$.55r,   r}   currentrz   c                    |D ]X  }| j                  |d       x}s|j                  |i       }t        |t              rt        |t              r
i ||||<   T|||<   Z i || S r   )popr{   r   dict)r}   r  rz   pathpath_updatepath_currents         r   r|   r|   W  sx     , **T400;0";;tR0L+t,L$1O ?< ?; ? +, !g   r,   rD   c                 L    	 t        j                  |       S # t        $ r Y yw xY w)Nunserializable)jsondumps	Exception)rD   s    r   r   r   b  s'     zz#   s    	##)0r   builtins@py_builtins_pytest.assertion.rewrite	assertionrewrite
@pytest_arimportlib.utilr   r  loggingr   r   collectionsr   	threadingr   typingr   rB   r	   r   r   langsmith.testing._internalr   rE   	getLoggerr   r   r   r+   __version__
startswithr0   r3   hookimplrM   rR   rT   r   r   r   r   r   r  r]   r|   r   r   r,   r   <module>r     s           	  #    ' 7			8	$
*! 
  &""
 T" 
 # 
F  u5 u5p+>3   S 3 3 !D !4 !DI !$ ! c  c  r,   