U
    ccf                     @   s  zd dl ZW n  ek
r,   ddlmZ Y nX 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Zd dlZejdk Zerzd dlZW n  ek
r   ddlmZ Y nX dd Zd	d
 Zdaejdddd Zdd Zdd Zdd ZG dd deZdd Zdd Zdd Z d8ddZ!d d! Z"da#d"d# Z$ej%dd$d%d& Z&d'd( Z'da(d)d* Z)ejd+d,d-d. Z*ejd/d,d0d1 Z+d2d3 Z,d4d5 Z-G d6d7 d7ej.Z/dS )9    N   )plugin_base)update_wrapper)   r   )reinvent_fixtures_py2kc                    s,   |  d  fdd}t| t  d S )NZ
sqlalchemyc                    sp   | 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-8u86ls_i/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"   )r   	__class__r
   r   r$   1   s    
zFpytest_addoption.<locals>.make_option.<locals>.CallableAction.__init__c                    s    ||| d S r	   r
   r   )r   r
   r   r   C   s    r   )FFN)N)r   r   r   r$   r   __classcell__r
   )r   r   )r%   r   r   0   s       )popargparseActionZ	addoption)namekwgroup)r   r   r   r   make_option!   s    z%pytest_addoption.<locals>.make_option)Zgetgroupr   Zsetup_optionsZread_config)r   r.   r
   r,   r   pytest_addoption   s    
+
r/   c                 C   s   | j dr| j t  t| drBt| j t| jd  n&| j	j
rhtj| j	j
rht| j	j
 t| j	 ttt| j	dd tt | j	jrdad S )NZxdistworkerinputfollower_identZ
cov_sourceFT)ZpluginmanagerZ	haspluginregister
XDistHookshasattrr   Z!restore_important_follower_configr0   Zconfigure_followeroptionZwrite_identsospathexistsremoveZ	pre_beginZset_coverage_flagboolgetattrZset_fixture_functionsPytestFixtureFunctionsdump_pyannotateDUMP_PYANNOTATEconfigr
   r
   r   pytest_configureP   s     

rA   FT)autousec                  c   s.   t rddlm}  |   d V  t r*|   d S )Nr   collect_types)r>   pyannotate_runtimerD   startstoprC   r
   r
   r   collect_types_fixturem   s    rH   c                 C   s   ddl m} |tj d S Nr   asyncio)sqlalchemy.testingrK   Z_assume_asyncr   Z
post_begin)sessionrK   r
   r
   r   pytest_sessionstartx   s    rN   c                 C   sB   ddl m} |tj | jjjr>ddlm	} |
| jjj d S )Nr   rJ   rC   )rL   rK   _maybe_async_provisioningr   Zfinal_process_cleanupr@   r5   r=   rE   rD   Z
dump_stats)rM   rK   rD   r
   r
   r   pytest_sessionfinish~   s
    
rP   c                    s>   | j jjr:ddlm} tjd  fdd}|j|d d S )Nr   rC   lib/sqlalchemyc                    s<   t jt j| } dt j|  gkr,d S d| kr8d S | S )NrQ   Ztesting)r6   r7   normpathabspath
commonpath)filenameZlib_sqlalchemyr
   r   _filter   s    z)pytest_collection_finish.<locals>._filter)Zfilter_filename)	r@   r5   r=   rE   rD   r6   r7   rS   Zinit_types_collection)rM   rD   rW   r
   rV   r   pytest_collection_finish   s
    
rX   c                   @   s   e Zd Zdd Zdd ZdS )r3   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   	provisionrJ   ztest_%s   r1   )rL   rZ   rK   r   Z!memoize_important_follower_configr0   uuidZuuid4hexrO   Zcreate_follower_db)r   noderZ   rK   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   rY   rJ   r1   )rL   rZ   rK   rO   Zdrop_follower_dbr0   )r   r^   errorrZ   rK   r
   r
   r   pytest_testnodedown   s     zXDistHooks.pytest_testnodedownN)r   r   r   r_   ra   r
   r
   r
   r   r3      s   r3   c                    s   ddl m} tdd dd |D |d d < tdd |D  fd	d
  fdd}|| g }|D ]2}|j}|kr|| |j  qp|	| qpt
r|D ]}t| qt|dd d|d d < d S )Nr   rJ   c                   S   s
   t tS r	   )collectionsdefaultdictlistr
   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.0itemr
   r
   r   
<listcomp>   s   z1pytest_collection_modifyitems.<locals>.<listcomp>c                 s   s   | ]}| tjV  qd S r	   )rh   ri   rj   rl   r
   r
   r   	<genexpr>   s     z0pytest_collection_modifyitems.<locals>.<genexpr>c                 3   s:   |   D ],}t|tjr. |D ]
}|V  q q|V  qd S r	   )collect
isinstanceri   Z	Collector)elementZ
inst_or_fnel)rq   r
   r   rq      s
    
z.pytest_collection_modifyitems.<locals>.collectc                     s|   D ]r} t | j| jD ]\}|| jk	r| j }ttjdtj}| tj} ||j	|dD ]}||j
 | q^qqd S )Nfrom_parentr*   parent)r   Zgenerate_sub_testsclsmoduler;   ri   rj   rh   Moduler   r*   append)Z
test_classZsub_clsZper_cls_dictctorry   fnrq   Zrebuilt_itemsZtest_classesr
   r   setup_test_classes   s     

z9pytest_collection_modifyitems.<locals>.setup_test_classesc                 S   s    |  tjj|  tjj| jfS r	   )rh   ri   rz   r*   rj   )rn   r
   r
   r   re      s    )key)rL   rK   rb   rc   setrO   rx   extendr*   r{   py2kr   Z"scan_for_fixtures_to_use_for_classsorted)rM   r@   itemsrK   r   Znewitemsrn   Zcls_r
   r~   r   pytest_collection_modifyitems   s0    	
r   c                    s   t |r\t||r\ddlm} |jr0t|}tt	j
dt	j
 fddt j|D S t |r jd k	rt j|rd S g S d S )Nr   r?   ru   c                    s   g | ]}|j  d qS )rv   )r   )rm   Zparametrize_cls	collectorr|   r
   r   ro     s   z-pytest_pycollect_makeitem.<locals>.<listcomp>)inspectisclassr   Z
want_classrL   r@   	any_async_apply_maybe_asyncr;   ri   rj   _parametrize_clsry   
isfunctionrx   Zwant_method)r   r*   objr@   r
   r   r   pytest_pycollect_makeitem  s     
r   c                 C   s   t | dr| j} q t| S )N__wrapped__)r4   r   r   iscoroutinefunctionr}   r
   r
   r   _is_wrapped_coroutine_function  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   rJ   _maybe_async_appliedFZtest_Tc                    s    j | f||S r	   )_maybe_asyncr}   argskwargsrJ   r
   r   
make_async5  s    z&_apply_maybe_async.<locals>.make_asyncr   )rL   rK   varsr   callablerr   classmethodr;   rk   r   __func___pytest_fn_decoratorr   setattrmroobjectr   )r   Zrecurser*   valueZis_classmethodr   Zdo_asyncrx   r
   rJ   r   r   &  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
   )rm   argnameparamsr
   r
   r   ro   O  s     z$_parametrize_cls.<locals>.<listcomp>c                 S   s   g | ]}|d  qS )r   r
   )rm   Z	_sa_paramr
   r
   r   ro   T  s     z*need argnames for class-based combinationsz,\s*rg   c                 s   s2   | ]*}|j d D ]}ttdd|V  qqdS )-z\W N)idsplitstrresub)rm   paramtokenr
   r
   r   rp   [  s    z#_parametrize_cls.<locals>.<genexpr>z%s_%s)__dict__r   	itertoolsproductzip	TypeErrorr   r   r   joinr   type__new__r   r{   )ry   rx   r   classesZfull_param_setZcls_variablesr   r   Zargname_splitargvalZparametrized_namer*   Znewclsr
   r
   r   r   F  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 rI   )rL   rK   rr   ri   ZFunction_current_classrO   r   Z!start_test_class_outside_fixturesrx   rh   rj   rn   rK   r
   r
   r   pytest_runtest_setupl  s    
r   )Zhookwrapperc              
   c   s  ddl m} ddlm} |tj|  d V  td k	r|d ksP|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 |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   rJ   )string_typesz__Original test failure__:
z
__Original test failure__:
z__Original test failure__)rL   rK   Zsqlalchemy.utilr   r   r   Z
after_testr   rh   ri   rj   _current_reportrO   Z stop_test_class_outside_fixturesrx   	Exceptionfailedr   Zlongreprtextrr   rd   tuple)rn   nextitemrK   r   er   r
   r
   r   pytest_runtest_teardown  sH    
 
r   c                 C   s,   ddl m} |tj| | jj| j| j d S rI   )	rL   rK   r   r   Zbefore_testry   r   rx   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   sr   ddl m} | j}t|dr(||j tr6t|  d V  trJt	|  t|dr`||j
 |tj| d S )Nr   rJ   setup_test_classteardown_test_class)rL   rK   rx   r4   r   r   r   r   Zrun_class_fixture_setupZrun_class_fixture_teardownr   r   Zstop_test_class)requestrK   rx   r
   r
   r   setup_class_methods  s    



r   functionc                 c   s   ddl m} | j}tr t|  t|dr6||j t|drL||j	 d V  |t
j| t|drv||j t|dr||j trt|  d S )Nr   rJ   
setup_testsetUptearDownteardown_test)rL   rK   instancer   r   Zrun_fn_fixture_setupr4   r   r   r   r   Zafter_test_fixturesr   r   Zrun_fn_fixture_teardown)r   rK   r   r
   r
   r   setup_test_methods  s     





r   c                 C   s$   t jjdkrt| S t| S d S )Nr   )sysversion_infomajorr   getfullargspec
getargspecr   r
   r
   r   r   '  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_env4  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groupedzPdef %(name)s(%(args)s):
    return %(__target_fn)s(%(__orig_fn)s, %(apply_kw)s)
)r   r   r   
pytestmark)r   r   dictr   updater;   __defaults__r   r   r   r4   r   )r}   add_positional_parametersspecmetadatar   Z	decoratedr   r   r   targetr
   r   decorate8  s6        

z&_pytest_fn_decorator.<locals>.decorate)r
   )Zsqlalchemy.util.langhelpersr   Zsqlalchemy.util.compatr   )r   r   r
   r   r   r   .  s
    "r   c                   @   sZ   e Zd Z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 )r<   c                 O   s   t jj||S r	   )ri   skipr   )r   r   r+   r
   r
   r   skip_test_exception^  s    z*PytestFixtureFunctions.skip_test_exceptionc                 C   s   t jddS )Nr   r   )ri   markZusefixturesr   r
   r
   r   mark_base_test_classa  s     z+PytestFixtureFunctions.mark_base_test_classc                 C   s   | S r	   r
   r   r
   r
   r   re   g  rf   zPytestFixtureFunctions.<lambda>c                 C   s   t | dr| jS t| jS )Nr   )r4   r   r   r   r
   r
   r   re   j  s    )irsnc              
      s  ddl m tjjdkr@t|dkrft|d drft|d }n&t|dkrft|d drft|d }|ddfd	d
}|dd}g }d|r6| j	 t
jddd t|D  } fddt|D }|D ]^ttsf|\}}	||dd }
|	rd||
|	dfdd|D f qnD|D ]>ttsPf|\}}	|	rfd|||	df q:g |D ]6\}
}	}r|
|	f7 }
tj|
d|i}| q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   r   __next__nextargnamesNc                    s<   g }g }| D ]&}t | jr(|| q|| q||fS r	   )rr   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
   rm   idxcharr
   r
   r   ro     s   z7PytestFixtureFunctions.combinations.<locals>.<listcomp>c                    s*   g | ]"\}}| krt | | fqS r
   )operator
itemgetterr  )_combination_id_fnsr
   r   ro     s   Tr   c                 3   s   | ]\}}|| V  qd S r	   r
   )rm   getterZcomb_fn)r   r
   r   rp     s    z6PytestFixtureFunctions.combinations.<locals>.<genexpr>r   c                    s   t | r:rtdd| jkr&g | _| j f | S  d krVt| jdd  }nt	d }r|dg7 }t
fdd}dd	 }|| d
d} tj|| S d S )Nz5exclusions not supported for class level combinationsr   r   z, *_exclusionsc                    s4   |d }|r"   j| }|| } | |dd |S )Nr   r   )r   add)r}   r   r+   r  Zexlur   r
   r   check_exclusions  s
    zOPytestFixtureFunctions.combinations.<locals>.decorate.<locals>.check_exclusionsc                 S   s   | j d d S )Nr  )r   r{   )r   r
   r
   r   process_metadata  s    zOPytestFixtureFunctions.combinations.<locals>.decorate.<locals>.process_metadata)r  )r   )r   r   NotImplementedErrorr   r   r{   r   r   r   r   r   ri   r   Zparametrize)r}   Z	_argnamesr  r  )r   r   has_exclusionspytest_paramsr
   r   r     s,    


 z5PytestFixtureFunctions.combinations.<locals>.decorate)r   )rL   r   r   r   r   lenr4   rd   r'   r	  r  r  	enumeraterr   r   r{   r   ri   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   combinationso  sn    	 


$z#PytestFixtureFunctions.combinationsc                 G   s    |d }t j|dd  d|iS )Nr   r   r   )ri   r   )r   r  identr
   r
   r   param_ident  s    z"PytestFixtureFunctions.param_identc                    s|   ddl m ddl m  t|dkrFt|d rF|d }|dd  }nd }tj| fdd}|rt||S |S d S )Nr   r?   rJ   r   c                    s6   j r | } tr*dkr*t|  n| } | S )NrB   )r   Z_maybe_async_wrapperr   r   Zadd_fixturer   rK   r@   fixturer+   r
   r   wrap  s    
z,PytestFixtureFunctions.fixture.<locals>.wrap)rL   r@   rK   r  r   ri   r  )r   r   r+   r}   r  r
   r  r   r    s    zPytestFixtureFunctions.fixturec                 C   s   t jdS )NZPYTEST_CURRENT_TEST)r6   environgetr   r
   r
   r   get_current_test_name*  s    z,PytestFixtureFunctions.get_current_test_namec                    s$   ddl m  t fdd}||S )Nr   rJ   c                    s    j | f|| d S r	   )Z_run_coroutine_functionr   rJ   r
   r   r   0  s    z3PytestFixtureFunctions.async_test.<locals>.decorate)rL   rK   r   )r   r}   r   r
   rJ   r   
async_test-  s    z!PytestFixtureFunctions.async_testN)r   r   r   r   r   reprr   r	  r  r  r  r  r  r
   r
   r
   r   r<   ]  s   	 
.r<   )T)0Zsqla_plugin_baser   ImportErrorr   r(   rb   	functoolsr   r   r   r  r6   r   r   r\   ri   r   r   Zsqla_reinvent_fixturesr   r/   rA   r>   r  rH   rN   rP   rX   r   r3   r   r   r   r   r   r   r   Zhookimplr   r   r   r   r   r   r   r   ZFixtureFunctionsr<   r
   r
   r
   r   <module>   s`   
2


P
 #

5



B/