o
    Zh2                     @   s@  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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eZdd	 Zd
d ZejdrPdd Zndd Zejdddd Zejdd ZG dd dZ dd Z!de"de#de"fddZ$d e"de#de"fd!d"Z%d#e&d$e&d%e'e" de&fd&d'Z(d(ede"fd)d*Z)dS )+zLangSmith Pytest hooks.    N)defaultdict)Lock)Any)utils)testc                 C   sD   z|  dd}|jddddd W d	S  ty!   td Y d	S w )
zaSet a boolean flag for LangSmith output.

    Skip if --langsmith-output is already defined.
    	langsmithZ	LangSmith--langsmith-output
store_trueFz'Use LangSmith output (requires 'rich').)actiondefaulthelpzCLangSmith output flag cannot be added because it's already defined.N)ZgetgroupZ	addoption
ValueErrorloggerwarning)parsergroup r   N/var/www/html/lang_env/lib/python3.10/site-packages/langsmith/pytest_plugin.pypytest_addoption   s   
r   c                    sf   t  fdddD r/t  fdddD s dd t  fddd	D s1 dd
 dS dS dS )zHandle output arguments.c                 3       | ]}| v V  qd S Nr   ).0optargsr   r   	<genexpr>+       z&_handle_output_args.<locals>.<genexpr>)r   c                 3   r   r   r   r   ar   r   r   r   -   r   )-qqr   r   c                 3   r   r   r   r   r   r   r   r   0   r   )-sz--capture=nor    N)anyinsertr   r   r   r   _handle_output_args)   s   r#   z7.c                 C   s   t | dS )zCCall immediately after command line options are parsed (pytest v7).Nr#   )configr   r   r   r   pytest_cmdline_preparse6      r&   c                 C   s   t |  dS )zHandle args in pytest v8+.Nr$   r   r   r   r   pytest_load_initial_conftests<   r'   r(   T)Zhookwrapperc                 c   s    |  d}|rP|r|jni }| j}tdi ||| _t| dd}|dur0d| jvr0|| jd< |durPd| jjvrPt| j| jjd | jj	| jj
| jjd| _dV  dS )zEApply LangSmith tracking to tests marked with @pytest.mark.langsmith.r   _requestNrequest)r*   )argnamesinitialnamesnames_closurename2fixturedefsr   )Zget_closest_markerkwargsobjls_testgetattrZfuncargsZ_fixtureinfor+   typer,   r-   r.   )itemmarkerr/   Zoriginal_funcZrequest_objr   r   r   pytest_runtest_callA   s"   



r6   c                 C   s   | drdS dS )z7Remove the short test-status character outputs ("./F").r   ) r7   r7   N)	getoption)reportr%   r   r   r   pytest_report_teststatusZ   s   
r:   c                   @   s^   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	de
fddZdd Zdd ZdS )LangSmithPluginz'Plugin for rendering LangSmith results.c                 C   sp   ddl m} ddlm} tt| _i | _i | _t	 | _
| | _||  | jdd| _| j  | jjd dS )zInitialize.r   )Console)Live
   )consolerefresh_per_secondzCollecting tests...N)rich.consoler<   Z	rich.liver=   r   listtest_suitestest_suite_urlsprocess_statusr   status_lockr?   generate_tableslivestartprint)selfr<   r=   r   r   r   __init__f   s   

zLangSmithPlugin.__init__c                 C   s&   t  | _|jD ]	}| j|j qdS )zHCall after collection phase is completed and session.items is populated.N)setZcollected_nodeidsitemsaddnodeid)rK   sessionr4   r   r   r   pytest_collection_finishx   s   
z(LangSmithPlugin.pytest_collection_finishc                 C   s   | j | | dS )z&Group a test case with its test suite.N)rC   append)rK   Z
test_suite
process_idr   r   r   add_process_to_test_suite~      z)LangSmithPlugin.add_process_to_test_suitec                 C   st   | j s
| jjd | j | j |i }t||g dd| j |< W d   n1 s+w   Y  | j|   dS )zUpdate test results.zRunning tests...)feedbackinputsreference_outputsoutputs)unpackN)	rE   rH   r?   rJ   rF   get_merge_statusesupdaterG   )rK   rT   statusZcurrent_statusr   r   r   update_process_status   s   z%LangSmithPlugin.update_process_statusc                 C   s   |  |ddi dS )z/Initialize live display when first test starts.r_   runningN)r`   )rK   rP   r   r   r   pytest_runtest_logstart   rV   z'LangSmithPlugin.pytest_runtest_logstartc                 C   s<   ddl m} g }| jD ]}| |}|| q|| }|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)rA   rc   rC   _generate_tablerS   )rK   rc   Ztables
suite_nametabler   r   r   r   rG      s   

zLangSmithPlugin.generate_tablesre   c                    sd  ddl m} j| }d| dj|  d}||dd}|d |d	 |d
 |d |d |d |d td}td}t }g }	tt}
fdd|D }|	 D ]G\}}|
d||
d| }|	| |
di 	 D ]\}}t|tttfr|
| | q|tt|dd|}tt|
dd|}q_tdd | D }tdd | D }|| r|||  }|dkrdnd}d| d |d!d"| d }nd#}|	rt|	t|	 dd}nd$}|
rd%d&d |
	 D }nd'}t|t|}jj||  d(  t d) |	 D ]~\}}d*ddd+d,
|
ddd-}|
d||
d| }d% fd.d|
di 	 D }t|
d/i }t|
d0i }t|
d1i }|tt| d2t| d2t| d2t| d2  d3 d| d |
dd d"| d ||dd q|d4d4d4d4d4d4d4 |d5d4d4d4||| |S )6zGenerate results table.r   )TablezTest Suite: [bold]z$[/bold]
LangSmith URL: [bright_cyan]z[/bright_cyan]left)titletitle_justifyZTestZInputszRef outputsZOutputsStatusZFeedbackZDurationr_   durationc                    s   i | ]}| j | qS r   )rE   )r   pid)rK   r   r   
<dictcomp>   s    z3LangSmithPlugin._generate_table.<locals>.<dictcomp>Zend_time
start_timerW   z.2fsZqueuedc                 s       | ]
}| d dkV  qdS )r_   passedNr\   r   rp   r   r   r   r          z2LangSmithPlugin._generate_table.<locals>.<genexpr>c                 s   rq   )r_   failedNrs   rt   r   r   r   r      ru      greenred[]z.0%z[/z
Passed: --z--s
c                 s   s.    | ]\}}| d t |t|  V  qdS ): N)sumlenr   kvr   r   r   r      s    
z--      yellowcyan)ra   rr   rv   Zskippedwhitec                 3   s<    | ]\}}t | d  dt|trt|n| V  qdS )max_lenr}   N)_abbreviate
isinstanceboolintr   )max_dynamic_col_widthr   r   r      s
    &
rX   rY   rZ   r   Nr7   z[bold]Averages[/bold])Z
rich.tablerg   rC   rD   
add_columnr   timer   rB   rN   r\   rS   r   floatr   r   maxr~   valuesjoinr?   width_dumps_with_fallbackadd_row_abbreviate_test_namestrr   )rK   re   rg   Zprocess_idsri   rf   Z
max_statusZmax_durationnowZ	durationsZnumeric_feedbacksZsuite_statusesrm   r_   rl   r   r   Zpassed_countZfailed_countZratecolorZaggregate_statusZaggregate_durationZaggregate_feedbackZstatus_colorrW   rX   rY   rZ   r   )r   rK   r   rd      s   

















zLangSmithPlugin._generate_tablec                 C   s*   d|j _|jd}|rdd |_dS dS )z9Disable warning reporting and show no warnings in output.Fzwarnings-pluginc                  _   s   d S r   r   )r   r/   r   r   r   <lambda>  s    z2LangSmithPlugin.pytest_configure.<locals>.<lambda>N)optionshowwarningspluginmanagerZ
get_pluginZwarning_summary)rK   r%   reporterr   r   r   pytest_configure  s
   z LangSmithPlugin.pytest_configurec                 C   s   | j   | j jd dS )z3Stop Rich Live rendering at the end of the session.z
Finishing up...N)rH   stopr?   rJ   )rK   rQ   r   r   r   pytest_sessionfinish  s   
z$LangSmithPlugin.pytest_sessionfinishN)__name__
__module____qualname____doc__rL   rR   rU   r`   rb   rG   r   rd   r   r   r   r   r   r   r;   c   s    h
r;   c                 C   sz   |  dd | dr;tjdsd}t|tjdr#d}t|t	
 r-d}t|| jt d	 d
| j_dS dS )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]'`Z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.Zlangsmith_output_pluginFN)Zaddinivalue_liner8   	importlibutil	find_specr   osenvironr\   ls_utilsZtest_tracking_is_disabledr   registerr;   r   r   )r%   msgr   r   r   r     s&   
r   xr   returnc                 C   s$   t | |kr| d |d  d S | S )N   ...)r   )r   r   r   r   r   r   :  s   r   	test_namec                 C   sn   t | |kr5| d\}}t d| |kr d||d  d   S |t d|  }d|| d   d | S | S )Nz::z.py::r   r   z...::)r   split)r   r   filer   Zfile_lenr   r   r   r   A  s   r   r^   currentr[   c                C   s`   |D ]'}|  |d  }r)||i }t|tr%t|tr%i ||||< q|||< qi || S r   )popr\   r   dict)r^   r   r[   pathZpath_updateZpath_currentr   r   r   r]   L  s   r]   r0   c                 C   s"   zt | W S  ty   Y dS w )NZunserializable)jsondumps	Exception)r0   r   r   r   r   W  s
   r   )*r   importlib.utilr   r   loggingr   r   collectionsr   	threadingr   typingr   Zpytestr   r   r   Zlangsmith.testing._internalr   r1   	getLoggerr   r   r   r#   __version__
startswithr&   r(   Zhookimplr6   r:   r;   r   r   r   r   r   r   rB   r]   r   r   r   r   r   <module>   s:    




 9