U
    ovgJT                     @  st  U d dl mZ d dlZd dlmZ d dlZd dlad dlZd dlm	Z	 d dl
Z
d dlZd dlmZ d dlmZ dZtdZdadadadadadadadZdadadadadae Z e Z!da"d	e#d
< dd Z$dd Z%dd Z&dd Z'dd Z(dd Z)dd Z*dd Z+dd Z,dd Z-dd  Z.d!d" Z/d#d$ Z0d%d& Z1d'd( Z2g Z3g Z4d)d* Z5d+d, Z6e5d-d. Z7e5d/d0 Z8e6d1d2 Z9e6d3d4 Z:e5d5d6 Z;e6d7d8 Z<e6d9d: Z=d;d< Z>e6d=d> Z?e6d?d@ Z@e6dAdB ZAdCdD ZBdEdF ZCdGdH ZDdIdJ ZEdKdL ZFdMdN ZGdOdP ZHdQdR ZIdSdT ZJdUdV ZKdWdX ZLdYdZ ZMded[d\ZNd]d^ ZOd_d` ZPG dadb dbejQZRdaSdcdd ZTdS )f    )annotationsN)	Namespace)Path)Any)asyncioFzsqlalchemy.testing.plugin_baser   optionsc                 C  s  | ddt tdd | ddt tdd | ddt d	d
d | ddtdd | ddt ddd | ddt ddd | ddddd | dddd | ddtddd | d dtd!d"d | d#dtd$d%d | d&dtd'd(d | d)t d*d+d,d- | d.t d/d0d1 | d2dd3d4d | d5t d6d7d1 | d8dt td9d | d:dtt d;d< | d=dtt d>d< | d?dd@dAdBdC | dDddEdAdFdC | dGt dHdId1 | dJt dg dKdLdM | dNt dOdP | dQddRd d S )SNz
--log-infocallbackz,turn on info logging for <LOG> (multiple OK))actiontyper   helpz--log-debugz-turn on debug logging for <LOG> (multiple OK)z--dbappenddbzBUse prefab database uri. Multiple OK, first one is run by default.)r	   r
   destr   z--dbszList available prefab dbs)r	   Zzeroarg_callbackr   z--dburidburiz8Database uri.  Multiple OK, first one is run by default.z
--dbdriverdbdriverz|Additional database drivers to include in tests.  These are linked to the existing database URLs by the provisioning system.z--dropfirst
store_true	dropfirstz,Drop all tables in the target database first)r	   r   r   z--disable-asyncioz8disable test / fixtures / provisoning running in asyncio)r	   r   z--backend-onlybackendz}Run only tests marked with __backend__ or __sparse_backend__; this is now equivalent to the pytest -m backend mark expressionz
--nomemoryZmemory_intensivezpDon't run memory profiling tests; this is now equivalent to the pytest -m 'not memory_intensive' mark expressionz--notimingintensiveZtiming_intensivezpDon't run timing intensive tests; this is now equivalent to the pytest -m 'not timing_intensive' mark expressionz--nomypyZmypyz_Don't run mypy typing tests; this is now equivalent to the pytest -m 'not mypy' mark expressionz--profile-sortZ
cumulativeprofilesortz*Type of sort for profiling standard output)r
   defaultr   r   z--profile-dumpprofiledumpz2Filename where a single profile run will be dumped)r
   r   r   z--low-connectionslow_connectionsz>Use a low number of distinct connections - i.e. for Oracle TNSz--write-identswrite_identszCwrite out generated follower idents to <file>, when -n<num> is usedz--requirementsz3requirements class for testing, overrides setup.cfgz--include-tagzAInclude tests with tag <tag>; legacy, use pytest -m 'tag' instead)r	   r   r
   r   z--exclude-tagzEExclude tests with tag <tag>; legacy, use pytest -m 'not tag' insteadz--write-profilesZwrite_profilesFz$Write/update failing profiling data.)r	   r   r   r   z--force-write-profilesZforce_write_profilesz,Unconditionally write/update profiling data.z--dump-pyannotateZdump_pyannotatez/Run pyannotate and dump json info to given filez--mypy-extra-test-pathZmypy_extra_test_pathszlAdditional test directories to add to the mypy tests. This is used only when running mypy tests. Multiple OK)r
   r	   r   r   r   z--postgresql-templatedbz^name of template database to use for PostgreSQL CREATE DATABASE (defaults to current database))r
   r   z--oracledb-thick-modez:enables the 'thick mode' when testing with oracle+oracledb)str_log	_list_dbs_set_tag_include_set_tag_exclude_requirements_opt_include_tag_exclude_tag)make_option r"   I/tmp/pip-unpacked-wheel-uqd9otp_/sqlalchemy/testing/plugin/plugin_base.pysetup_options;   s@   		
r$   c                 C  s   ddl m} | |_dS )zConfigure required state for a follower.

    This invokes in the parent process and typically includes
    database creation.

    r   	provisionN)sqlalchemy.testingr&   FOLLOWER_IDENT)Zfollower_identr&   r"   r"   r#   configure_follower   s    r)   c                 C  s   dS )zStore important configuration we will need to send to a follower.

    This invokes in the parent process after normal config is set up.

    Hook is currently not used.

    Nr"   Zdict_r"   r"   r#   !memoize_important_follower_config   s    r+   c                 C  s   dS )zRestore important configuration needed by a follower.

    This invokes in the follower process.

    Hook is currently not used.

    Nr"   r*   r"   r"   r#   !restore_important_follower_config  s    r,   c                 C  s*   t  att| d t| d g d S )Nz	setup.cfgztest.cfg)configparserConfigParserfile_configreadr   )	root_pathr"   r"   r#   read_config  s    r2   c                 C  s   | a tD ]}|t t qdS )z7things to set up early, before coverage might be setup.N)r   pre_configurer/   )optfnr"   r"   r#   	pre_begin  s    r6   c                 C  s
   | t _d S N)r   Zhas_coverage)valuer"   r"   r#   set_coverage_flag   s    r9   c                  C  sp   t D ]} | tt qddlma ddlmamama ddlm	a	m
a
ma ddlmama ddlma t
  dS )z9things to set up later, once we know coverage is running.r   testing)fixturesengines
exclusions)
assertionswarnings	profiling)configr&   )utilN)post_configurer   r/   
sqlalchemyr;   r'   r<   r=   r>   r?   r@   rA   rB   r&   rC   Zsetup_filtersr5   r"   r"   r#   
post_begin$  s    rG   c                 C  sR   t sdd l a t   | dr2t |t j n| drNt |t j d S )Nr   z-infoz-debug)loggingbasicConfigendswith	getLoggersetLevelINFODEBUGopt_strr8   parserr"   r"   r#   r   6  s    

r   c                  G  sV   t d krtt  td tt dD ]}td|t d|f  q*t	d d S )Nz0Available --db options (use --dburi to override)r   z%20s	%sr   )
r/   r2   r   cwdprintsortedr   getsysexit)argsmacror"   r"   r#   r   C  s    r   c                 C  s   t | d S r7   )_setup_requirementsrO   r"   r"   r#   r   N  s    r   c                   s    fdd}|S )Nc                   s   t |  | d S r7   )r   rO   tagr"   r#   _do_include_tagS  s    z)_set_tag_include.<locals>._do_include_tagr"   )r\   r]   r"   r[   r#   r   R  s    r   c                   s    fdd}|S )Nc                   s   t |  | d S r7   )r    rO   r[   r"   r#   _do_exclude_tagZ  s    z)_set_tag_exclude.<locals>._do_exclude_tagr"   )r\   r^   r"   r[   r#   r   Y  s    r   c                 C  s   t |dd d S N-_)exclude_tagsaddreplacerO   r"   r"   r#   r    `  s    r    c                 C  s   t |dd d S r_   )include_tagsrc   rd   rO   r"   r"   r#   r   d  s    r   c                 C  s   t |  | S r7   )r3   r   rF   r"   r"   r#   prel  s    
rf   c                 C  s   t |  | S r7   )rD   r   rF   r"   r"   r#   postq  s    
rg   c                 C  s   | a d S r7   r   r4   r/   r"   r"   r#   _setup_optionsv  s    rj   c                 C  s,   ddl m} |ddd |ddd d S )Nr   )registryzsqlite.pysqlite_numericz#sqlalchemy.dialects.sqlite.pysqliteZ_SQLiteDialect_pysqlite_numericzsqlite.pysqlite_dollarZ_SQLiteDialect_pysqlite_dollar)Zsqlalchemy.dialectsrk   register)r4   r/   rk   r"   r"   r#    _register_sqlite_numeric_dialect|  s    rm   c              
   C  s^   t jdddkrZddlm} z|dd W n, tk
rX } ztd|W 5 d }~X Y nX d S )	NZREQUIRE_SQLALCHEMY_CEXT01r   )has_compiled_extT)Zraise_zEREQUIRE_SQLALCHEMY_CEXT is set but can't import the cython extensions)osenvironrU   Zsqlalchemy.utilrp   ImportErrorAssertionError)r4   r/   rp   errr"   r"   r#   __ensure_cext  s    rv   c                 C  s   ddl m} t |_d S Nr   rB   )r'   rB   _fixture_fn_classZ_fixture_functions)r   r/   rB   r"   r"   r#   _init_symbols  s    rz   c                 C  s   | j rdt_d S )NF)Zdisable_asyncior   ZENABLE_ASYNCIOri   r"   r"   r#   _set_disable_asyncio  s    r{   c              
     sp  ddl m} ddlm} ddlm} ddlm  | jrBt| j}ng }| j	pNg }| j
r| j
D ]D}td|D ]2}||dkrtd| ql||d| qlq\|s||dd	 d |_| jr|jr fd
d|D D ]<}	t| jd&}
|
|j d|	jdd d W 5 Q R X qt|||}|D ]8}	td|	 ||	| ||j}|js2||| q2d S )Nr   r:   rx   r%   )urlz[,\s]+r   z:Unknown URI specifier '%s'.  Specify --dbs for known uris.r   c                   s   g | ]}  |qS r"   )Zmake_url).0db_urlZsa_urlr"   r#   
<listcomp>  s     z_engine_uri.<locals>.<listcomp>a F)Zhide_password
zAdding database URL: %s)rE   r;   r'   rB   r&   Zsqlalchemy.enginer|   r   listr   r   resplitr   RuntimeErrorr   rU   _currentr   r(   openwriteZrender_as_stringZgenerate_db_urlsloginfoZsetup_configZset_as_current)r   r/   r;   rB   r&   Zdb_urlsZextra_driversZdb_tokenr   r~   file_Zexpanded_urlscfgr"   r   r#   _engine_uri  sL    

   r   c                 C  s   | dd}t| d S )Nsqla_testingrequirement_cls)rU   rZ   )r   r/   r   r"   r"   r#   _requirements  s    r   c                 C  sr   ddl m} ddlm} | d\}}t|}|ddd  D ]}t||}q@t||}|  |_|_t	|_	d S )Nr   rx   r:   :.   )
r'   rB   rE   r;   r   
__import__getattrrequirementsrequiresbootstrapped_as_sqlalchemy)argumentrB   r;   modnameZclsnamemod	componentZreq_clsr"   r"   r#   rZ     s    
rZ   c                 C  s@   ddl m} | jr<ddl m} |j D ]}|||j q(d S )Nr   rx   r%   )r'   rB   r   r&   Configall_configsZdrop_all_schema_objectsr   )r   r/   rB   r&   r   r"   r"   r#   _prep_testing_database  s
    r   c                 C  s   ddl m} t|_||_d S rw   )r'   rB   r   r/   )r4   r/   rB   r"   r"   r#   _post_setup_options  s    r   c                 C  s.   ddl m} |j|dd| j| jd|_d S )Nr   )rA   r   Zprofile_file)sortdump)r'   rA   ZProfileStatsFilerU   r   r   Z_profile_stats)r   r/   rA   r"   r"   r#   _setup_profiling  s    
r   c                 C  s&   t |tjsdS | drdS dS d S )NFra   T)
issubclassr<   ZTestBase
startswith)nameclsr"   r"   r#   
want_class  s
    
r   c                 C  s&   |j dsdS |jd krdS dS d S )NZtest_FT)__name__r   
__module__)r   r5   r"   r"   r#   want_method  s
    
r   c           	      c  s   d|ksd|krd|k}t | |dD ]\}| j}tdd|j}tdd|}d| j|f }t|| f||d	}t||| |V  q$n| V  d S )
Nr   Zsparse_backend)sparsez
[_\[\]\.]+ra   z_+$ z%s_%s)_sa_orig_cls_name__only_on_config__)_possible_configs_for_clsr   r   subr   r
   setattr)	r   modulemarkersr   r   	orig_nameZ
alpha_namer   subclsr"   r"   r#   generate_sub_tests!  s    
r   c                 C  s   t |  t|  d S r7   )	_do_skips_setup_enginer   r"   r"   r#   !start_test_class_outside_fixtures9  s    r   c                 C  s   t |  tj  d S r7   )r<   Zstop_test_class_inside_fixturesr=   testing_reaperr   r"   r"   r#   stop_test_class>  s    
r   c                 C  s:   t j  tttj|  ztjs*t	
  W 5 t  X d S r7   )r=   r    stop_test_class_outside_fixturesr&   rB   r   _restore_enginer   r   r?   global_cleanup_assertionsr   r"   r"   r#   r   G  s    
r   c                   C  s   t jrt jt d S r7   )rB   r   resetr;   r"   r"   r"   r#   r   Q  s    r   c                   C  s   t j  t  t  d S r7   )r=   r   Zfinal_cleanupr?   r   r   r"   r"   r"   r#   final_process_cleanupV  s    
r   c                 C  s<   t | dd r8t| j}d|d< tj|d}tj|t d S )N__engine_options__classZscoperh   )	r   dictr   r=   Ztesting_enginerB   r   Zpush_enginer;   )r   optsZengr"   r"   r#   r   \  s
    
r   c                 C  s*   t |d|j}d|||f }t| d S )Nr   z%s.%s.%s)r   r   rA   Z_start_current_test)testZtest_module_nameZ
test_classZ	test_namer   Zid_r"   r"   r#   before_testd  s    r   c                 C  s   t   tj  d S r7   )r<   
after_testr=   r   r   r"   r"   r#   r   o  s    r   c                 C  s   t j|  d S r7   )r=   r   Zafter_test_outside_fixturesr   r"   r"   r#   after_test_fixturest  s    r   c                 C  s  t tj }| jr@tj| j }t|D ]}||r(|| q(t	| dd r~tjt
| j }t|D ]}||sf|| qft	| dd r|| jg t| drtj}t|D ]H}| jD ]<}t	||}||}	|	r|| |d k	r||	  qqqt| drft  }
tj}t|D ]4}| jD ]&}t	||}||s$|
| q$q||
rf||
 |ri }tt|dd dD ] }|jj}||kr|||< q| S |S )N__only_on__r   __requires____prefer_requires__c                 S  s   | j j| j j| j jjfS r7   )r   r   driverdialectZserver_version_info)r   r"   r"   r#   <lambda>  s    z+_possible_configs_for_cls.<locals>.<lambda>)key)setrB   r   r   Z__unsupported_on__r>   db_specr   remover   rC   to_listr   intersection_updater   hasattrr   r   Zmatching_config_reasonsextendr   Zenabled_for_configrc   
differencedifference_updatereversedrT   r   r   values)r   reasonsr   r   spec
config_objr   requirementcheckZskip_reasonsnon_preferredZper_dialectr   r   r"   r"   r#   r   x  s^    










r   c                 C  s   g }t | |}t| ddrFt| dD ] }| r$td| j|jf  q$|sd| j| jddd tj D d|f }t| nRt	| drt
 }tjt| j }|D ]}||s|| q||r|| tj|krt| |  d S )	NZ__skip_if__Fz'%s' skipped by %sz1'%s.%s' unsupported on any DB implementation %s%sz, c              	   s  s<   | ]4}d |j jddd t|j D |j jf V  qdS )z'%s(%s)+%s'r   c                 s  s   | ]}t |V  qd S r7   )r   )r}   digr"   r"   r#   	<genexpr>  s   z&_do_skips.<locals>.<genexpr>.<genexpr>N)r   r   joinr>   Z_server_versionr   )r}   r   r"   r"   r#   r     s   


z_do_skips.<locals>.<genexpr>__prefer_backends__)r   r   rB   Z	skip_testr   r   r   r   r   r   r   r>   r   rC   r   r   rc   r   r   r   _setup_configpop)r   r   r   cmsgr   r   r   r"   r"   r#   r     s8    






r   c                 C  s   t j| t d S r7   )rB   r   pushr;   )r   ctxr"   r"   r#   r     s    r   c                   @  sn   e Zd Zejdd Zejdd Zejdd Zejdd Zd	d
 Z	ejddddZ
ejdd ZdS )FixtureFunctionsc                 O  s
   t  d S r7   NotImplementedErrorselfargkwr"   r"   r#   skip_test_exception  s    z$FixtureFunctions.skip_test_exceptionc                 O  s
   t  d S r7   r   r   rX   r   r"   r"   r#   combinations  s    zFixtureFunctions.combinationsc                 O  s
   t  d S r7   r   r   r"   r"   r#   param_ident  s    zFixtureFunctions.param_identc                 O  s
   t  d S r7   r   r   r"   r"   r#   fixture  s    zFixtureFunctions.fixturec                 C  s
   t  d S r7   r   r   r"   r"   r#   get_current_test_name  s    z&FixtureFunctions.get_current_test_namer   )returnc                 C  s
   t  d S r7   r   r   r"   r"   r#   mark_base_test_class  s    z%FixtureFunctions.mark_base_test_classc                 C  s
   t  d S r7   r   r   r"   r"   r#   add_to_marker  s    zFixtureFunctions.add_to_markerN)r   r   __qualname__abcabstractmethodr   r   r   r   r   r   abstractpropertyr   r"   r"   r"   r#   r     s   



r   c                 C  s   | a d S r7   )ry   )Zfixture_fn_classr"   r"   r#   set_fixture_functions	  s    r  )NF)U
__future__r   r  argparser   r-   rH   rq   pathlibr   r   rV   typingr   r'   r   r   rK   r   r<   r=   r>   r@   rA   r&   r?   r   rB   r;   rC   r/   r   re   rb   r   __annotations__r$   r)   r+   r,   r2   r6   r9   rG   r   r   r   r   r   r    r   r3   rD   rf   rg   rj   rm   rv   rz   r{   r   r   rZ   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   ABCr   ry   r  r"   r"   r"   r#   <module>
   s    
 6







1





			

B+