U
    ovgl                     @  s  d dl mZ d dlZd dlZd dl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Zd dlmZ d dlZd dlZzesd dlZW n  ek
r   ddlmZ Y nX dd Zd	d
ddZdaejdddd Zdd Zdd Zdd Zdd Zdd ZG dd dZdd Zd d! Z d"d# Z!d<d$d%Z"d&d' Z#da$d(d) Z%ej&dd*d+d, Z'd-d. Z(da)d/d0 Z*ejd1d2d3d4 Z+ejd5d2d6d7 Z,d8d9 Z-G d:d; d;ej.Z/dS )=    )annotationsN)update_wrapper)TYPE_CHECKING   )plugin_basec                   s$   |  d  fdd}t| d S )N
sqlalchemyc                   sn   | dd   r.G  fdddtj}||d< | dd r\G fdddtj}||d< j| f| d S )Ncallbackc                      s   e Zd Zd fdd	ZdS )=pytest_addoption.<locals>.make_option.<locals>.CallableActionNc                   s    ||| d S N selfparser	namespacevaluesoption_string	callback_r   J/tmp/pip-unpacked-wheel-uqd9otp_/sqlalchemy/testing/plugin/pytestplugin.py__call__*   s    Fpytest_addoption.<locals>.make_option.<locals>.CallableAction.__call__)N)__name__
__module____qualname__r   r   r   r   r   CallableAction)   s    r   actionzeroarg_callbackc                      s,   e Zd Zd fdd	Zdfdd	Z  ZS )	r	   FNc              	     s   t  j||dd|||d d S )Nr   T)option_stringsdestnargsconstdefaultrequiredhelp)super__init__)r   r   r   r!   r"   r#   	__class__r   r   r%   5   s    zFpytest_addoption.<locals>.make_option.<locals>.CallableAction.__init__c                   s    ||| d S r
   r   r   r   r   r   r   G   s    r   )FFN)N)r   r   r   r%   r   __classcell__r   r(   r&   r   r   4   s       )popargparseActionZ	addoption)namekwr   group)r   r   r   make_option%   s    z%pytest_addoption.<locals>.make_option)Zgetgroupr   Zsetup_options)r   r1   r   r/   r   pytest_addoption"   s    
+r2   zpytest.Configconfigc                 C  s  t | j t jst jr`dtt jdd t jD  }| jjrX| j jd| 7  _n|| j_| j	
drz| j	t  t| drt | j t | jd  n&| jjrtj| jjrt| jj t | j t tt| jdd t t | jjrd	ad S )
Nz and c                 S  s   g | ]}d | qS )znot r   ).0tagr   r   r   
<listcomp>X   s     z$pytest_configure.<locals>.<listcomp>Zxdistworkerinputfollower_identZ
cov_sourceFT)r   Zread_configZrootpathexclude_tagsZinclude_tagsjoinlistoptionZmarkexprpluginmanagerZ	haspluginregister
XDistHookshasattrZ!restore_important_follower_configr8   Zconfigure_followerZwrite_identsospathexistsremoveZ	pre_beginZset_coverage_flagboolgetattrZset_fixture_functionsPytestFixtureFunctionsdump_pyannotateDUMP_PYANNOTATE)r4   Znew_exprr   r   r   pytest_configureS   s4    


rK   FT)Zautousec                  c  s.   t rddlm}  |   d V  t r*|   d S )Nr   collect_types)rJ   pyannotate_runtimerM   startstoprL   r   r   r   collect_types_fixture|   s    rQ   c                 C  s   dd l }ddl m} ddlm} ddlm} d}tjjr<dnd}d| d	| d
d|j	 g}| rddl
m} |d|j	 d n|d|  | jjd}	|	r|	d| |D ]}
|	|
 qntd|d |D ]}
t|
 qd S )Nr   )__version__)has_compiled_ext)_CYEXTENSION_MSGzsqlalchemy installationzno user sitezuser site loadedzSQLAlchemy z ()zPath: )utilz!compiled extension enabled, e.g.  z compiled extension not enabled; Zterminalreporter=z=========================)r   rR   Zsqlalchemy.utilrS   Zsqlalchemy.util._has_cyrT   sysflagsno_user_site__file__Zsqlalchemy.cyextensionrV   appendr4   r>   Z
get_pluginZ	write_sepZ
write_lineprint)sessionr   rR   rS   rT   ZgreetsiteZmsgsrV   Zpmmr   r   r   _log_sqlalchemy_info   s*    
rb   c                 C  s$   ddl m} t|  |tj d S Nr   asyncio)sqlalchemy.testingre   rb   Z_assume_asyncr   Z
post_begin)r_   re   r   r   r   pytest_sessionstart   s    rg   c                 C  sB   ddl m} |tj | jjjr>ddlm	} |
| jjj d S )Nr   rd   rL   )rf   re   _maybe_async_provisioningr   Zfinal_process_cleanupr4   r=   rI   rN   rM   Z
dump_stats)r_   re   rM   r   r   r   pytest_sessionfinish   s
    
ri   c                 C  s   ddl m} |  d S rc   )rf   re   	_shutdown)r4   re   r   r   r   pytest_unconfigure   s    rk   c                   s>   | j jjr:ddlm} tjd  fdd}|j|d d S )Nr   rL   lib/sqlalchemyc                   s<   t jt j| } dt j|  gkr,d S d| kr8d S | S )Nrl   Ztesting)rB   rC   normpathabspath
commonpath)filenameZlib_sqlalchemyr   r   _filter   s    z)pytest_collection_finish.<locals>._filter)Zfilter_filename)	r4   r=   rI   rN   rM   rB   rC   rn   Zinit_types_collection)r_   rM   rr   r   rq   r   pytest_collection_finish   s
    
rs   c                   @  s   e Zd Zdd Zdd ZdS )r@   c                 C  sX   ddl m} ddl m} t|j dt jdd  |jd< |	|j
|jd  d S )Nr   	provisionrd   ztest_%s   r9   )rf   ru   re   r   Z!memoize_important_follower_configr8   uuidZuuid4hexrh   Zcreate_follower_db)r   noderu   re   r   r   r   pytest_configure_node   s     z XDistHooks.pytest_configure_nodec                 C  s0   ddl m} ddl m} ||j|jd  d S )Nr   rt   rd   r9   )rf   ru   re   rh   Zdrop_follower_dbr8   )r   ry   errorru   re   r   r   r   pytest_testnodedown   s     zXDistHooks.pytest_testnodedownN)r   r   r   rz   r|   r   r   r   r   r@      s   r@   c                   s   ddl m} tdd dd |D |d d < dd |D  fd	d
  fdd}|| g }|D ]2}|j}|kr|| |j  ql|| qlt	|dd d|d d < d S )Nr   rd   c                   S  s
   t tS r
   )collectionsdefaultdictr<   r   r   r   r   <lambda>       z/pytest_collection_modifyitems.<locals>.<lambda>c                 S  s4   g | ],}| tjd k	r| tjjds|qS )N_)	getparentpytestClassr-   
startswithr5   itemr   r   r   r7      s   z1pytest_collection_modifyitems.<locals>.<listcomp>c                 S  s   h | ]}| tjqS r   )r   r   r   r   r   r   r   	<setcomp>  s     z0pytest_collection_modifyitems.<locals>.<setcomp>c                 3  s4   |   D ]&}t|tjr( |E d H  q|V  qd S r
   )collect
isinstancer   Z	Collector)elementZ
inst_or_fn)r   r   r   r     s    z.pytest_collection_modifyitems.<locals>.collectc            
        s
  D  ]} t  }t| jdds,t| jddr4dh}nt| jddrJdh}nt }dd |  D }|| }||}|D ]}| | qxt| j| j	|D ]h}|| jk	r| j }| 
tj}tjj|j|d	}|D ]}|| qԈ |D ]}	||	j |	 qqqd S )
NZ__backend__FZ__only_on__backendZ__sparse_backend__Zsparse_backendc                 S  s   h | ]
}|j qS r   )r-   )r5   markr   r   r   r     s    zLpytest_collection_modifyitems.<locals>.setup_test_classes.<locals>.<setcomp>r-   parent)setrG   cls	frozensetZiter_markersunionZ
add_markerr   Zgenerate_sub_testsmoduler   r   Moduler   from_parentr   r-   r]   )
Z
test_classZadd_markersZexisting_markersZall_markersmarkerZsub_clsZper_cls_dictr   Znew_clsfnr   Zrebuilt_itemsZtest_classesr   r   setup_test_classes  sD    
  
  

 z9pytest_collection_modifyitems.<locals>.setup_test_classesc                 S  s    |  tjj|  tjj| jfS r
   )r   r   r   r-   r   )r   r   r   r   r   E  s    )key)
rf   re   r}   r~   rh   r   extendr-   r]   sorted)r_   r4   itemsre   r   Znewitemsr   Zcls_r   r   r   pytest_collection_modifyitems   s*    *
r   c                   sx   t |rJt||rJddlm} |jr0t|} fddt j	|D S t 
|rp jd k	rpt j|rpd S g S d S )Nr   r3   c                   s   g | ]}t jj|j d qS )r   )r   r   r   r   )r5   Zparametrize_cls	collectorr   r   r7   T  s
    z-pytest_pycollect_makeitem.<locals>.<listcomp>)inspectisclassr   Z
want_classrf   r4   	any_async_apply_maybe_async_parametrize_clsr   
isfunctionr   Zwant_method)r   r-   objr4   r   r   r   pytest_pycollect_makeitemM  s    

r   c                 C  s   t | dr| j} q t| S )N__wrapped__)rA   r   r   iscoroutinefunctionr   r   r   r   _is_wrapped_coroutine_functiong  s    
r   c                   s   ddl m  t|  D ]\}}t|s2t|trt|dds|drt	|sd}t|trh|j
}d}t fdd}||}|rt|}d|_t| || q|r|  d	d  D ]}|tkrt|d q| S )
Nr   rd   _maybe_async_appliedFZtest_Tc                   s    j | f||S r
   )_maybe_asyncr   argskwargsrd   r   r   
make_async}  s    z&_apply_maybe_async.<locals>.make_asyncr   )rf   re   varsr   callabler   classmethodrG   r   r   __func___pytest_fn_decoratorr   setattrmroobjectr   )r   Zrecurser-   valueZis_classmethodr   Zdo_asyncr   r   rd   r   r   n  s8    

r   c                 C  s   d|j kr|gS |j}g }tjdd |D  D ]}i }tdd |D |D ]>\}}|s^tdtd|}t||jD ]\}	}
|
||	< qvqJd	dd	 |D }d
|j
|f }tt||f|}t| || || q.|S )z6implement a class-based version of pytest parametrize._sa_parametrizec                 S  s   g | ]\}}|qS r   r   )r5   argnameparamsr   r   r   r7     s     z$_parametrize_cls.<locals>.<listcomp>c                 S  s   g | ]}|d  qS )r   r   )r5   Z	_sa_paramr   r   r   r7     s     z*need argnames for class-based combinationsz,\s*r   c                 s  s.   | ]&}|j d D ]}tdd|V  qqdS )-z\W N)idsplitresub)r5   paramtokenr   r   r   	<genexpr>  s    z#_parametrize_cls.<locals>.<genexpr>z%s_%s)__dict__r   	itertoolsproductzip	TypeErrorr   r   r   r;   r   type__new__r   r]   )r   r   r   classesZfull_param_setZcls_variablesr   r   Zargname_splitargvalZparametrized_namer-   Znewclsr   r   r   r     s2    
 
r   c                 C  s@   ddl m} t| tjr<td kr<|tj| j	 | 
tjad S rc   )rf   re   r   r   ZFunction_current_classrh   r   Z!start_test_class_outside_fixturesr   r   r   r   re   r   r   r   pytest_runtest_setup  s    
r   )Zhookwrapperc              
   c  s  ddl m} |tj|  d V  td k	r|d ksD|tjtk	rd azz|
tj| j W n tk
r } z|t	jr|jsdt	j f|_nZ|jd rt|jd trt|j}|d  dt	j 7  < t||_n| jdt	jf7  _ W 5 d }~X Y nX W 5 d a	X d S )Nr   rd   z__Original test failure__:
z
__Original test failure__:
z__Original test failure__)rf   re   r   r   Z
after_testr   r   r   r   _current_reportrh   Z stop_test_class_outside_fixturesr   	Exceptionfailedr   Zlongreprtextr   strr<   tuple)r   nextitemre   er   r   r   r   pytest_runtest_teardown  sF    
 
r   c                 C  s,   ddl m} |tj| | jj| j| j d S rc   )	rf   re   r   r   Zbefore_testr   r   r   r-   r   r   r   r   pytest_runtest_call  s    r   c                 C  s   | j dkr| ad S )Ncall)whenr   )reportr   r   r   pytest_runtest_logreport  s    
r   class)Zscopec                 c  sV   ddl m} | j}t|dr(||j d V  t|drD||j |tj| d S )Nr   rd   setup_test_classteardown_test_class)	rf   re   r   rA   r   r   r   r   Zstop_test_class)requestre   r   r   r   r   setup_class_methods  s    

r   functionc                 c  s   ddl m} | j}t|dr(||j t|dr>||j d V  |tj| t|drh||j	 t|dr~||j
 d S )Nr   rd   
setup_testsetUptearDownteardown_test)rf   re   instancerA   r   r   r   r   Zafter_test_fixturesr   r   )r   re   r   r   r   r   setup_test_methods$  s    





r   c                   s8   ddl m ddlm dd  d	 fdd	}|S )
z:Port of langhelpers.decorator with pytest-specific tricks.r   )format_argspec_plus)inspect_getfullargspecc                 S  s   t | | || S r
   )exec)codeenvfn_namer   r   r   _exec_code_in_envi  s    
z/_pytest_fn_decorator.<locals>._exec_code_in_envr   c                   s   | }|r|j | tdd| jd}||dd d| } || d| j}|szt| d| j|_| |_t|| S | j	|_	| j|_t
| d	r| j|_|S d S )
N__target_fn	__orig_fn)r   r   r-   F)ZgroupedzVdef %(name)s%(grouped_args)s:
    return %(__target_fn)s(%(__orig_fn)s, %(apply_kw)s)
)r   r   r   
pytestmark)r   r   dictr   updaterG   __defaults__r   r   r   rA   r   )r   add_positional_parametersspecmetadatar   Z	decoratedr   r   r   targetr   r   decorateq  s6        

z&_pytest_fn_decorator.<locals>.decorate)r   )Zsqlalchemy.util.langhelpersr   Zsqlalchemy.util.compatr   )r  r  r   r   r   r   c  s
    !r   c                   @  sf   e Zd Zdd Zedd Zdd Zdd eed	d d
Z	dd Z
dd Zdd Zdd Zdd ZdS )rH   c                 O  s   t jj||S r
   )r   skipr   )r   r   r.   r   r   r   skip_test_exception  s    z*PytestFixtureFunctions.skip_test_exceptionc                 C  s   t jS r
   )r   r   r   r   r   r   add_to_marker  s    z$PytestFixtureFunctions.add_to_markerc                 C  s   t jddS )Nr   r   )r   r   Zusefixturesr  r   r   r   mark_base_test_class  s     z+PytestFixtureFunctions.mark_base_test_classc                 C  s   | S r
   r   r   r   r   r   r     r   zPytestFixtureFunctions.<lambda>c                 C  s   t | dr| jS t| jS )Nr   )rA   r   r   r  r   r   r   r     s    )irsnc              
     s  ddl m t|dkr2t|d dr2t|d }|ddfdd}|d	d}g }d
|r | j tjddd t	|D  } fddt	|D }|D ]\t
tsf|\}}	||dd }
|	rd||
|	dfdd|D f qnD|D ]>t
tsf|\}}	|	r0d|||	df qg |D ]6\}
}	}rf|
|	f7 }
tj|
d|i}| qLfdd}|S )a  Facade for pytest.mark.parametrize.

        Automatically derives argument names from the callable which in our
        case is always a method on a class with positional arguments.

        ids for parameter sets are derived using an optional template.

        r   
exclusionsr   __next__argnamesNc                   s<   g }g }| D ]&}t | jr(|| q|| q||fS r
   )r   compoundr]   )r   resultZgathered_exclusionsar  r   r   _filter_exclusions  s    z?PytestFixtureFunctions.combinations.<locals>._filter_exclusionsid_Fc                 S  s   g | ]\}}|d kr|qS ))r  r
  r  r  r   r5   idxcharr   r   r   r7     s   z7PytestFixtureFunctions.combinations.<locals>.<listcomp>c                   s*   g | ]"\}}| krt | | fqS r   )operator
itemgetterr  )_combination_id_fnsr   r   r7     s   Tr   c                 3  s   | ]\}}|| V  qd S r
   r   )r5   getterZcomb_fn)r   r   r   r     s    z6PytestFixtureFunctions.combinations.<locals>.<genexpr>r   c                   s   t | r:rtdd| jkr&g | _| j f | S t | jdd  } d kr\|}nt	d }rt
dd |D }d| }||g7 }tfdd	}|| |fd
} tj|| S d S )Nz5exclusions not supported for class level combinationsr   r   z, *c                 s  s   | ]}| d rdV  qdS )_exclusionsr   N)r   )r5   r  r   r   r   r     s    
 zHPytestFixtureFunctions.combinations.<locals>.decorate.<locals>.<genexpr>Z_exclusions_c                   s4   |d }|r"   j| }|| } | |d d |S )Nr   )r  add)r   r   r.   r  Zexlur  r   r   check_exclusions!  s
    zOPytestFixtureFunctions.combinations.<locals>.decorate.<locals>.check_exclusions)r   )r   r   NotImplementedErrorr   r   r]   getfullargspecr   r   r   sumr   r   r   Zparametrize)r   Z_fn_argnamesZ	_argnamesZexisting_exlZcurrent_exclusion_namer  )r  r  has_exclusionspytest_paramsr   r   r  	  s4    



 z5PytestFixtureFunctions.combinations.<locals>.decorate)r   )rf   r  lenrA   r<   r*   r  r  r  	enumerater   r   r]   r;   r   r   )r   Zarg_setsr.   r  r  Ztobuild_pytest_paramsZ_arg_getterfnsZ	fn_paramsZparam_exclusions
parametersr   r  r   )r  r   r  r  r#  r$  r   combinations  sh    	 


&z#PytestFixtureFunctions.combinationsc                 G  s    |d }t j|dd  d|iS )Nr   r   r   )r   r   )r   r(  identr   r   r   param_ident1  s    z"PytestFixtureFunctions.param_identc                   sz   ddl m ddl m  t|dkrFt|d rF|d }|dd  }nd }tj|| fdd}|rr||S |S d S )Nr   r3   rd   r   c                   s   j r | } | } | S r
   )r   Z_maybe_async_wrapperr   re   r4   fixturer   r   wrapK  s    
z,PytestFixtureFunctions.fixture.<locals>.wrap)rf   r4   re   r%  r   r   r-  )r   r   r.   r   r.  r   r,  r   r-  5  s    
zPytestFixtureFunctions.fixturec                 C  s   t jdS )NZPYTEST_CURRENT_TEST)rB   environgetr  r   r   r   get_current_test_nameZ  s    z,PytestFixtureFunctions.get_current_test_namec                   s$   ddl m  t fdd}||S )Nr   rd   c                   s    j | f|| d S r
   )Z_run_coroutine_functionr   rd   r   r   r  `  s    z3PytestFixtureFunctions.async_test.<locals>.decorate)rf   re   r   )r   r   r  r   rd   r   
async_test]  s    z!PytestFixtureFunctions.async_testN)r   r   r   r  propertyr  r  reprr   r  r)  r+  r-  r1  r2  r   r   r   r   rH     s   
	 %rH   )T)0
__future__r   r+   r}   	functoolsr   r   r   r  rB   r   rY   typingr   rw   r   Zsqla_plugin_baser   ImportErrorr   r2   rK   rJ   r-  rQ   rb   rg   ri   rk   rs   r@   r   r   r   r   r   r   r   Zhookimplr   r   r   r   r   r   r   ZFixtureFunctionsrH   r   r   r   r   <module>	   s\   1&


 a
 !

5



>2