
    6|hI3                     H   d 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
Z
ddlmZ ddlmZ d Zd Ze
j&                  j)                  d	      rd
 Znd Z e
j.                  d      d        Ze
j.                  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y)zLangSmith Pytest hooks.    N)defaultdict)Lock)utils)testc                 X    | j                  dd      }|j                  dddg dd       y	)
z+Set CLI options for choosing output format.	langsmith	LangSmith--outputstorepytest)r   lsr   z|Choose output format: 'langsmith' | 'ls' (rich custom LangSmith output) or 'pytest' (standard pytest). Defaults to 'pytest'.)actiondefaultchoiceshelpN)getgroup	addoption)parsergroups     V/var/www/html/test/engine/venv/lib/python3.12/site-packages/langsmith/pytest_plugin.pypytest_addoptionr      s4    OOK5E	OO-7  
    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     
H33$;
H   )z--output=langsmithz--output=lsc              3   &   K   | ]  }|v  
 y wr   r   r   ar   s     r   r    z&_handle_output_args.<locals>.<genexpr>$   s     8198r!   )z-q--quietr   r%   c              3   &   K   | ]  }|v  
 y wr   r   r#   s     r   r    z&_handle_output_args.<locals>.<genexpr>'   s     =19=r!   )-sz--capture=nor'   N)anyinsertr   s   `r   _handle_output_argsr+       sW    

H"G
HH8&788KK9%=&<==KK4  > Ir   z7.c                     t        |       y)zCCall immediately after command line options are parsed (pytest v7).Nr+   )configr   s     r   pytest_cmdline_preparser/   -   
    D!r   c                     t        |        y)zHandle args in pytest v8+.Nr-   r*   s    r   pytest_load_initial_conftestsr2   3   r0   r   T)hookwrapperc              #     K   | j                  d      }|r|r|j                  ni }| j                  } t        di ||      | _        t	        | dd      }|d| j
                  vr|| j
                  d<    t        | j                        | j                  j                  dz   | j                  j                  | j                  j                  | j                  j                        | _        d yw)zEApply LangSmith tracking to tests marked with @pytest.mark.langsmith.r   _requestNrequest)r6   )argnamesinitialnamesnames_closurename2fixturedefsr   )get_closest_markerkwargsobjls_testgetattrfuncargstype_fixtureinfor7   r8   r9   r:   )itemmarkerr<   original_funcrequest_objs        r   pytest_runtest_callrG   8   s      $$[1F #)b$7$V$]3dJ5"y'E'2DMM)$ 7T%6%6 7**33lB!..;;"//==!%!2!2!C!C	!D 
s   C.C0c                 ,    |j                  d      dv ryy)z7Remove the short test-status character outputs ("./F").r
   r   r   ) rJ   rJ   N)	getoption)reportr.   s     r   pytest_report_teststatusrM   P   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.consolerQ   	rich.liverR   r   listtest_suitestest_suite_urlsprocess_statusr   status_lockrT   generate_tableslivestartprint)selfrQ   rR   s      r   __init__zLangSmithPlugin.__init__\   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)ra   sessionrC   s      r   pytest_collection_finishz(LangSmithPlugin.pytest_collection_finishn   s7    !$MM 	4D""&&t{{3	4r   c                 @    | j                   |   j                  |       y)z&Group a test case with its test suite.N)rY   append)ra   
test_suite
process_ids      r   add_process_to_test_suitez)LangSmithPlugin.add_process_to_test_suitet   s    $++J7r   c                     | j                   s%| j                  j                  j                  d       | j                  5  | j                   j                  |i       }|j                  d      r(i |j                  di       |j                  d      |d<   |j                  d      r(i |j                  di       |j                  d      |d<   |j                  d      r(i |j                  di       |j                  d      |d<   |j                  d      r(i |j                  di       |j                  d      |d<   i ||| 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outputsN)	r[   r^   rT   r`   r\   getpopupdater]   )ra   rn   statuscurrent_statuss       r   update_process_statusz%LangSmithPlugin.update_process_statusx   s    ""II##$67 	K!0044ZDNzz*%.$((R8.jj,.z* zz(#,$((26,jj*,x( zz-.7$(()<bA7jj!45723 zz)$-$((B7-jj+-y) /K.J6.JD
+-	K. 			--/0/	K 	Ks   DFFc                 ,    | j                  |ddi       y)z/Initialize live display when first test starts.rx   runningN)rz   )ra   rh   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)rV   r   rY   _generate_tablerl   )ra   r   tables
suite_nametabler   s         r   r]   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       |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   t        d      z   z
  d&z  t#        d'      |j                         D ]{  \  }}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/        j0                  |j                  d-i             }t/        j0                  |j                  d.i             }t/        j0                  |j                  d/i             }|j3                  t5        t7        |      0      t9        |0      t9        |0      t9        |0       d1 d| d|j                  dd       d | d||dd|j                  d2      rd3nd4       ~ |r1t%        d5 |j'                         D              t        |      z  }|d}nd%}|j3                  d4d4d4d4d4d4d4       |j3                  d6d4d4d4||||       |S c c}w )7zGenerate results table.r   )TablezTest Suite: [bold]z+[/bold]
LangSmith link: [bright_cyan][link=u&   ]⌘ + click here[/link][/bright_cyan]left)titletitle_justifyTestInputszRef outputsOutputsStatusFeedbackDurationLoggedrx   durationend_time
start_timerq   z.2fsqueuedc              3   D   K   | ]  }|j                  d       dk(    yw)rx   passedNru   r   r   s     r   r    z2LangSmithPlugin._generate_table.<locals>.<genexpr>        X1155?h6X    c              3   D   K   | ]  }|j                  d       dk(    yw)rx   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   :=rr   rs   rt   r   NloggedxrJ   c              3   @   K   | ]  }|j                  d d        yw)r   FNr   r   s     r   r    z2LangSmithPlugin._generate_table.<locals>.<genexpr>  s     QAx/Qs   z[bold]Summary[/bold])
rich.tabler   rY   rZ   
add_columnr   timer   rX   r[   rf   ru   rl   r   floatr   r   maxr   valuesjoinrT   widthjsondumpsadd_row_abbreviate_test_namestrr   ) ra   r   r   process_idsr   r   
max_statusmax_durationnow	durationsnumeric_feedbackspidsuite_statusesrx   r   r   r   passed_countfailed_countratecoloraggregate_statusaggregate_durationaggregate_feedbackstatus_colorrq   rr   rs   rt   r   aggregate_loggedr   s                                   @r   r   zLangSmithPlugin._generate_table   s   $&&z2&zl 3$$($8$8$D#EEko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LL*|";c(m"KL! !$$91 =)//1 	KC#!!	
 c&**Xx0':  zz*c2VZZc5RRHyy !"JJz26<<>! H ZZ

8R 89F $

6::6I2+N OjjIr!:;GMM%c#h8MNF,AB-7LMG-BC**+ L>6::h#A"B"\NRSTC."zz(+!	: Q9N9N9PQQTWU F #)# 	b"b"b"b1"		
 q Ps   >S-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)ra   r.   reporters      r   pytest_configurez LangSmithPlugin.pytest_configure  s9     &+" ''223DE'CH$ r   c                 8    | j                   j                          y)z3Stop Rich Live rendering at the end of the session.N)r^   stop)ra   ri   s     r   pytest_sessionfinishz$LangSmithPlugin.pytest_sessionfinish&  s    		r   N)__name__
__module____qualname____doc__rb   rj   ro   rz   r}   r]   r   r   r   r   r   r   r   rO   rO   Y   s>    17$481>Bq# qfDr   rO   c                    | j                  dd       | j                  d      dv 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
   rI   richzxMust have 'rich' installed to use --output='langsmith' | 'ls'. Please install with: `pip install -U 'langsmith[pytest]'`PYTEST_XDIST_TESTRUNUIDzp--output='langsmith' | 'ls' not supported with pytest-xdist. Please remove the '--output' option or '-n' option.z--output='langsmith' | 'ls' not supported when env varLANGSMITH_TEST_TRACKING='false'. Please remove the '--output' option or enable test tracking.langsmith_output_pluginFN)addinivalue_linerK   	importlibutil	find_spec
ValueErrorosenvironru   ls_utilstest_tracking_is_disabledr   registerrO   r   r   )r.   msgs     r   r   r   +  s    
D 
#'::~~''/L  S/!::>>34F  S/!--/+ 
 S/!%%o&79RS%*"- ;r   r   r   returnc                 8    t        |       |kD  r| d |dz
   dz   S | S )N   ...)r   )r   r   s     r   r   r   I  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   P  s    
9~__T*
dw~(4'A+ 0111S400tXIJ''$.55r   ) r   importlib.utilr   r   r   r   collectionsr   	threadingr   r   r   r   r   langsmith.testing._internalr   r>   r   r+   __version__
startswithr/   r2   hookimplrG   rM   rO   r   r   r   r   r   r   r   r   <module>r	     s       	  #   ' 7 ! 
  &""
 T"
 #
.  O Od+<3   S 3 3 r   