a
    ܌xd                     @   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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mZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlm Z  ddlm!Z! ddlm"Z" ddlm#Z# ddlm$Z$ ddlm%Z% ddlm&Z& ddlm'Z' ddlm(Z( ddl)m*Z* ddl)m+Z+ ddl)m,Z, ddl-Z.ddl/Z.ddl0Z.ddl1m2Z2 ddl1m3Z3 ddl4m5Z5 dd l-m6Z6 dd!l-m7Z7 dd"l8m9Z9 dd#l:m;Z; dd$l:m<Z< dd%l=m>Z> dd&l=m?Z? dd'l@mAZA dd(l@mBZB dd)l@mCZC dd*l@mDZD dd+l@mEZE dd,lFmGZG dd-lHmIZI dd.lHmJZJ e'rdd/lKmLZL dd0lMmNZN dd1lOmPZP eQZRe*d2ZSe+d2ZTe;G d3d4 d4ejUZVG d5d6 d6eWZXe.jYjZe[d7d8d9Z\de!e(e e] d:f  e!e"e(e]eRf   e(e^eVf d;d<d=Z_e^d>d?d@Z`G dAdB dBZae]e]e]dCdDdEZbe]e]e]dCdFdGZcdHZdeddIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]d^d_d`gejedakrdbdcgng ddR  ZfegefZhehide ehidf de!e e]  e!e"e(e]eRf   dgd;dhdiZjdjd>dkdlZkde!e(e e] d:f  e!e"e(e]eRf   dgd;dmdnZleedodpdqZmee]e%e]drf ee]e[f dsdtduZne;G dvdj dje,Zoe(dejpe]e"e] f e e] dwdxdyZqe]ddzd{d|ZrG d}d~ d~Zses Ztee] ee] dddZue;G ddg dgZve[d>ddZwdeve!e$ e9dddZxe]e[dddZyedde]e[e%de]e&ez e]e^f dddZ{e]e&ez dddZ|ee] ee] ddddZ}dS )z:Command line options, ini-file and conftest.py processing.    N)	lru_cache)Path)dedent)FunctionType)TracebackType)Any)Callable)cast)Dict)	Generator)IO)Iterable)Iterator)List)Optional)Sequence)Set)TextIO)Tuple)Type)TYPE_CHECKING)Union)HookimplMarker)HookspecMarker)PluginManager   )	PrintHelp)
UsageError)determine_setup)ExceptionInfo)filter_traceback)TerminalWriter)final)importlib_metadata)fail)Skipped)absolutepath)bestrelpath)import_path)
ImportMode)resolve_package_path)Stash)PytestConfigWarning)warn_explicit_for)_TracebackStyle)TerminalReporter)Argumentpytestc                   @   s(   e Zd ZdZdZdZdZdZdZdZ	dS )	ExitCodezEncodes the valid exit codes by pytest.

    Currently users and plugins may supply other exit codes as well.

    .. versionadded:: 5.0
    r   r               N)
__name__
__module____qualname____doc__OKZTESTS_FAILEDZINTERRUPTEDINTERNAL_ERRORUSAGE_ERRORZNO_TESTS_COLLECTED r>   r>   O/var/www/html/Ranjet/env/lib/python3.9/site-packages/_pytest/config/__init__.pyr2   T   s   r2   c                       sB   e Zd Zeeee eef dd fddZe	dddZ
  ZS )ConftestImportFailureN)pathexcinforeturnc                    s   t  || || _|| _d S N)super__init__rA   rB   )selfrA   rB   	__class__r>   r?   rF   l   s    zConftestImportFailure.__init__rC   c                 C   s   d | jd j| jd | jS )Nz{}: {} (from {})r   r   )formatrB   r7   rA   rG   r>   r>   r?   __str__u   s    zConftestImportFailure.__str__)r7   r8   r9   r   r   r   	Exceptionr   rF   strrM   __classcell__r>   r>   rH   r?   r@   k   s
   	r@   )entryrC   c                 C   s   t | odt| jtjvS )zFilter tracebacks entries which point to pytest internals or importlib.

    Make a special case for importlib because we use it to import test modules and conftest files
    in _pytest.pathlib.import_path.
    	importlib)r    rO   rA   splitossep)rQ   r>   r>   r?   ,filter_traceback_for_conftest_import_failure{   s    rV   zos.PathLike[str])argspluginsrC   c              
   C   s  z"zt | |}W n ty } zt|j}ttj}|jd|j	 ddd |j
t|_
|j
rr|jdddn| }t|}| D ]}|j| dd qtjW  Y d}~W S d}~0 0 zV|jj|d	}	zt|	W W |  W S  ty
   |	 Y W |  W S 0 W |  n
|  0 W nZ ty~ } z@ttj}|jD ]}
|jd
|
 ddd qFtjW  Y d}~S d}~0 0 dS )zPerform an in-process test run.

    :param args: List of command line arguments.
    :param plugins: List of plugin objects to be auto-registered during initialization.

    :returns: An exit code.
    z$ImportError while loading conftest 'z'.T)redshortF)stylechainNconfigzERROR: 
)_prepareconfigr@   r   Zfrom_exc_inforB   r!   sysstderrlinerA   	tracebackfilterrV   getreprZexconlyrO   
splitlinesrstripr2   r=   hookZpytest_cmdline_main_ensure_unconfigure
ValueErrorr   rW   )rW   rX   r^   eexc_infotwZexc_reprZformatted_tbrc   retmsgr>   r>   r?   main   sH    



rq   rJ   c                  C   sR   zt  } tj  | W S  tyL   ttjtj}t	|tj
  Y dS 0 dS )zoThe CLI entry point of pytest.

    This function is not meant for programmable use; use `main()` instead.
    r   N)rq   ra   stdoutflushBrokenPipeErrorrT   opendevnullO_WRONLYdup2fileno)coderv   r>   r>   r?   console_main   s    
r{   c                   @   s   e Zd ZeeZdS )cmdlineN)r7   r8   r9   staticmethodrq   r>   r>   r>   r?   r|      s   r|   )rA   optnamerC   c                 C   s"   t j| rt| d|  | S )ztArgparse type validator for filename arguments.

    :path: Path of filename.
    :optname: Name of the option.
    z must be a filename, given: rT   rA   isdirr   rA   r~   r>   r>   r?   filename_arg   s    r   c                 C   s"   t j| st| d|  | S )zvArgparse type validator for directory arguments.

    :path: Path of directory.
    :optname: Name of the option.
    z must be a directory, given: r   r   r>   r>   r?   directory_arg   s    r   )markrq   runnerZfixturesZ
helpconfigpythonZterminal	debuggingZunittestcaptureZskippingZ
legacypathZtmpdirZmonkeypatchZrecwarnZpastebinnose	assertionZjunitxmldoctestcacheproviderZfreeze_supportZ	setuponlyZ	setupplanstepwisewarningsloggingZreportsZpython_path)r4      ZunraisableexceptionZthreadexceptionfaulthandlerZpytesterZpytester_assertionsConfigc                 C   sT   t  }t|tj| pd|t dd}| d ur<|j| dd tD ]}|| q@|S )Nr>   rW   rX   dirinvocation_paramsTexclude_only)PytestPluginManagerr   InvocationParamsr   cwdconsider_preparsedefault_pluginsimport_plugin)rW   rX   pluginmanagerr^   specr>   r>   r?   
get_config  s    	r   r   c                   C   s   t  jS )zObtain a new instance of the
    :py:class:`pytest.PytestPluginManager`, with default plugins
    already loaded.

    This function can be used by integration with other tools, like hooking
    into pytest to run tests into an IDE.
    )r   r   r>   r>   r>   r?   get_plugin_manager&  s    r   c                 C   s   | d u rt jdd  } n<t| tjr2t| g} n"t| tsTd}t|| t	| t
| |}|j}zD|r|D ]$}t|tr|| qn|| qn|jj|| d}|W S  ty   |   Y n0 d S )Nr   zG`args` parameter expected to be a list of strings, got: {!r} (type: {}))r   rW   )ra   argv
isinstancerT   PathLikefspathlist	TypeErrorrK   typer   r   rO   consider_pluginargregisterri   pytest_cmdline_parseBaseExceptionrj   )rW   rX   rp   r^   r   pluginr>   r>   r?   r`   1  s.    


r`   rA   rC   c                 C   s   |   r| jS | S dS )z<Get the directory of a path - itself if already a directory.N)is_fileparent)rA   r>   r>   r?   _get_directoryQ  s    r   .)method	hook_type	opt_namesrC   c           
      C   s   t rt| sJ dd t| dg D }g }i }|D ]`}t| |t}|turj|| d|  d||< q4||v r|| d d||< q4d||< q4|rd|}tjj	j
|| j|d	}	ttt| |	 |S )
Nc                 S   s   h | ]
}|j qS r>   name).0mr>   r>   r?   	<setcomp>a      z)_get_legacy_hook_marks.<locals>.<setcomp>Z
pytestmark=Tz=TrueF, )r   fullname	hook_opts)r   inspect	isroutinegetattrAttributeErrorappendjoin_pytest
deprecatedZHOOK_LEGACY_MARKINGrK   r9   r-   r	   r   )
r   r   r   Zknown_marksZ	must_warnoptsopt_nameZopt_attrr   messager>   r>   r?   _get_legacy_hook_marksY  s.    



r   c                       s  e Zd ZdZdd fddZeed fddZed	 fd
dZdCee	e e	e d fddZ
ed	ddZeedddZdddddZejeddddZeedddZeeeef edddd Zeeeef eeej d!d"d#Zeeeeef eeejef d$d%d&Zeeeef eejd'd(d)Zejedd*d+d,Zd-d.ee edd/d0d1Z edd2d3d4Z!ejdd5d6d7Z"ddd8d9Z#ejdd:d;d<Z$edejeee f dd=d>d?Z%dDeedd@dAdBZ&  Z'S )Er   a;  A :py:class:`pluggy.PluginManager <pluggy.PluginManager>` with
    additional pytest-specific functionality:

    * Loading plugins from the command line, ``PYTEST_PLUGINS`` env variable and
      ``pytest_plugins`` global variables found in plugins being loaded.
    * ``conftest.py`` loading during start-up.
    NrJ   c                    s   dd l }t d t | _i | _d | _d| _tdt	| _	t | _
g | _| |j | |  tjdrtj}t|dd}z tt| |jd|d	}W n ty   Y n0 | jj|j |   |j  | _!d| _"d S )
Nr   r1   F   ZPYTEST_DEBUGencodingutf8r   )mode	bufferingr   )#_pytest.assertionrE   rF   set_conftest_plugins_dirpath2confmods_confcutdir_noconftestr   r   Z_duplicatepathsskipped_pluginsZadd_hookspecshookspecr   rT   environgetra   rb   r   ru   dupry   r   rN   tracerootZ	setwriterwriteZenable_tracingr   ZDummyRewriteHookrewrite_hook_configured)rG   r   errr   rH   r>   r?   rF     s6    

zPytestPluginManager.__init__)r   r   c                    sX   | dsd S |dkrd S t ||}|d ur4|S t||}t|sLd S t|ddS )Npytest_pytest_pluginsimpl)ZtryfirsttrylastZoptionalhookhookwrapper)
startswithrE   parse_hookimpl_optsr   r   r   r   )rG   r   r   r   r   rH   r>   r?   r     s    


z'PytestPluginManager.parse_hookimpl_optsr   c                    s:   t  ||}|d u r6t||}|dr6t|dd}|S )Nr   r   )ZfirstresultZhistoric)rE   parse_hookspec_optsr   r   r   )rG   Zmodule_or_classr   r   r   rH   r>   r?   r     s    

z'PytestPluginManager.parse_hookspec_opts)r   r   rC   c              	      sp   |t jjv r,ttd|dd d S t 	||}|rl| j
jjt|| dd t|tjrl| | |S )NzQ{} plugin has been merged into the core, please remove it from your requirements._-)r   managerkwargs)r   r   ZDEPRECATED_EXTERNAL_PLUGINSr   warnr,   rK   replacerE   r   ri   Zpytest_plugin_registeredcall_historicdictr   types
ModuleTypeconsider_module)rG   r   r   ro   rH   r>   r?   r     s"    


zPytestPluginManager.registerc                 C   s   |  |}|S rD   )
get_plugin)rG   r   r   r>   r>   r?   	getplugin  s    
zPytestPluginManager.getpluginr   rC   c                 C   s   t | |S )z:Return whether a plugin with the given name is registered.)boolr   )rG   r   r>   r>   r?   	hasplugin  s    zPytestPluginManager.haspluginr   )r^   rC   c                 C   s"   | dd | dd d| _dS ):meta private:markersztryfirst: mark a hook implementation function such that the plugin machinery will try to call it first/as early as possible. DEPRECATED, use @pytest.hookimpl(tryfirst=True) instead.ztrylast: mark a hook implementation function such that the plugin machinery will try to call it last/as late as possible. DEPRECATED, use @pytest.hookimpl(trylast=True) instead.TN)addinivalue_liner   )rG   r^   r>   r>   r?   pytest_configure  s    z$PytestPluginManager.pytest_configure)	namespacerootpathrC   c           
      C   s   t  }|jrt||j nd| _|j| _|j| _|j	}d}|D ]R}t
|}|d}|dkrj|d| }t|| }	|	 r@| |	|j| d}q@|s| ||j| dS )a`  Load initial conftest files given a preparsed "namespace".

        As conftest files may add their own command line options which have
        arguments ('--my-opt somepath') we might get some false positives.
        All builtin and 3rd party plugins will have been loaded, however, so
        common options will not confuse our logic here.
        NFz::T)r   r   
confcutdirr&   r   Z
noconftestr   pyargs_using_pyargsfile_or_dirrO   findexists_try_load_conftest
importmode)
rG   r   r   current	testpathsZfoundanchorZtestpathrA   ianchorr>   r>   r?   _set_initial_conftests  s(    

z*PytestPluginManager._set_initial_conftestsr   c                 C   s   | j du rdS || j jvS )z`Whether a path is within the confcutdir.

        When false, should not load conftest.
        NT)r   parents)rG   rA   r>   r>   r?   _is_in_confcutdir1  s    
z%PytestPluginManager._is_in_confcutdir)r  r	  r   rC   c                 C   s@   |  ||| | r<|dD ]}| r |  ||| q d S )Nztest*)_getconftestmodulesis_dirglob)rG   r  r	  r   xr>   r>   r?   r  :  s
    z&PytestPluginManager._try_load_conftest)rA   r	  r   rC   c           
      C   s   | j r
g S | |}| j|}|d ur,|S g }t|g|jR D ]6}| |rB|d }| rB| |||}	|	|	 qB|| j|< |S )Nzconftest.py)
r   r   r   r   reversedr  r  r   _importconftestr   )
rG   rA   r	  r   	directoryZexisting_clistZclistr   conftestpathmodr>   r>   r?   r  D  s    


z'PytestPluginManager._getconftestmodules)r   rA   r	  r   rC   c              	   C   sV   | j |||d}t|D ]0}z|t||fW   S  tyF   Y qY q0 qt|d S N)r   )r  r  r   r   KeyError)rG   r   rA   r	  r   modulesr  r>   r>   r?   _rget_with_confmod_  s    z&PytestPluginManager._rget_with_confmod)r  r	  r   rC   c              
   C   s"  |  t|}|d ur"ttj|S t|}|d u r<t|j zt|||d}W nN t	y } z6|j
d uslJ t|||j
f}t|||W Y d }~n
d }~0 0 | || | j| |j}	|	| jv r| j D ]0\}
}|	|
jv s|
|	kr||vsJ || q| d| | | |S )N)r   r   zloading conftestmodule )r   rO   r	   r   r   r*   _ensure_removed_sysmodulestemr(   rN   __traceback__r   r@   _check_non_top_pytest_pluginsr   addr   r   itemsr  r   r   consider_conftest)rG   r  r	  r   existingpkgpathr  rl   rm   dirpathrA   Zmodsr>   r>   r?   r  n  s.    
"
z#PytestPluginManager._importconftest)r  r  rC   c                 C   s4   t |dr0| jr0| js0d}t||| jdd d S )Nr   af  Defining 'pytest_plugins' in a non-top-level conftest is no longer supported:
It affects the entire test suite instead of just below the conftest as expected.
  {}
Please move it to a top level conftest file at the rootdir:
  {}
For more information, visit:
  https://docs.pytest.org/en/stable/deprecations.html#pytest-plugins-in-non-top-level-conftest-filesF)Zpytrace)hasattrr   r  r$   rK   r   )rG   r  r  rp   r>   r>   r?   r!    s    	z1PytestPluginManager._check_non_top_pytest_pluginsFr   )rW   r   rC   c                C   s   d}t |}||k r|| }|d7 }t|tr|dkrbz|| }W n tyV   Y dS 0 |d7 }n|dr|dd }nq| }|r|dsq| | qdS )r   r   r   z-pNr3   no:)lenr   rO   
IndexErrorr   stripr   )rG   rW   r   r  noptZpargr>   r>   r?   r     s&    


z%PytestPluginManager.consider_preparse)argrC   c                 C   s   | drj|dd }|tv r*td| |dkrF| d | d | | | ds| d|  nX|}| j|d	du r| j|= | ds| jd| d	du r| jd| = | j|d
d dS )r   r)  r4   Nzplugin %s cannot be disabledr   r   Zpytest_stepwiser   r  T)consider_entry_points)r   essential_pluginsr   Zset_blockedZ_name2pluginr   r   )rG   r/  r   r>   r>   r?   r     s"    





z&PytestPluginManager.consider_pluginarg)conftestmodulerC   c                 C   s   | j ||jd dS )r   r   N)r   __file__)rG   r2  r>   r>   r?   r$    s    z%PytestPluginManager.consider_conftestc                 C   s   |  tjd dS )r   ZPYTEST_PLUGINSN)_import_plugin_specsrT   r   r   rL   r>   r>   r?   consider_env  s    z PytestPluginManager.consider_env)r  rC   c                 C   s   |  t|dg  dS )r   r   N)r4  r   )rG   r  r>   r>   r?   r     s    z#PytestPluginManager.consider_module)r   rC   c                 C   s    t |}|D ]}| | qd S rD   )_get_plugin_specs_as_listr   )rG   r   rX   Zimport_specr>   r>   r?   r4    s    z(PytestPluginManager._import_plugin_specs)modnamer0  rC   c              
   C   s  t |tsJ d| | |s.| |dur2dS |tv rBd| n|}| j| |rl| jd|d}|rldS zt| W n t	y } z0t	d| d|j
d  |j|W Y d}~nXd}~0  ty } z"| j||jpd	f W Y d}~n d}~0 0 tj| }| || dS )
zImport a plugin with ``modname``.

        If ``consider_entry_points`` is True, entry point names are also
        considered to find a plugin.
        z$module name as text required, got %rNz_pytest.pytest11r   zError importing plugin "z": r    )r   rO   
is_blockedr   builtin_pluginsr   mark_rewriteload_setuptools_entrypoints
__import__ImportErrorrW   with_tracebackr   r%   r   r   rp   ra   r  r   )rG   r7  r0  Z
importspecZloadedrl   r  r>   r>   r?   r     s2    
,
z!PytestPluginManager.import_plugin)N)F)(r7   r8   r9   r:   rF   _PluggyPluginrO   r   r   r   r   r   r   r   r   argparse	Namespacer   r  r  r   r)   r  r   r   r   r  r   r   r  r  r!  r   r   r$  r5  r   r4  r   rP   r>   r>   rH   r?   r   y  s`   5 !

!)specsrC   c                 C   s^   | du rg S t | tjrg S t | tr8| r4| dS g S t | tjjrNt| S t	d|  dS )z:Parse a plugins specification into a list of plugin names.N,zYPlugins may be specified as a sequence or a ','-separated string of plugin names. Got: %r)
r   r   r   rO   rS   collectionsabcr   r   r   )rD  r>   r>   r?   r6    s    
r6  )r7  rC   c                 C   s$   zt j| = W n ty   Y n0 d S rD   )ra   r  r  )r7  r>   r>   r?   r  )  s    r  c                   @   s   e Zd Zdd ZdS )Notsetc                 C   s   dS )Nz<NOTSET>r>   rL   r>   r>   r?   __repr__1  s    zNotset.__repr__N)r7   r8   r9   rI  r>   r>   r>   r?   rH  0  s   rH  )package_filesrC   c                 c   s   t | } d}| D ]z}d|vo$|d}|ddko<|d}|rptj|\}}|dkr|dsd}|V  q|rtj|}d}|V  q|sg }| D ].}|d}	d	|	dd	 }
|
r|
|
 q|rt|E d	H  d	S )
aM  Given an iterable of file names in a source distribution, return the "names" that should
    be marked for assertion rewrite.

    For example the package "pytest_mock/__init__.py" should be added as "pytest_mock" in
    the assertion rewrite mechanism.

    This function has to deal with dist-info based distributions and egg based distributions
    (which are still very much in use for "editable" installs).

    Here are the file names as seen in a dist-info based distribution:

        pytest_mock/__init__.py
        pytest_mock/_version.py
        pytest_mock/plugin.py
        pytest_mock.egg-info/PKG-INFO

    Here are the file names as seen in an egg based distribution:

        src/pytest_mock/__init__.py
        src/pytest_mock/_version.py
        src/pytest_mock/plugin.py
        src/pytest_mock.egg-info/PKG-INFO
        LICENSE
        setup.py

    We have to take in account those two distribution flavors in order to determine which
    names should be considered for assertion rewriting.

    More information:
        https://github.com/pytest-dev/pytest-mock/issues/167
    F/z.pyr   z__init__.pysetupZ__editable__TN)r   endswithcountrT   rA   splitextr   dirnamerS   r   r   _iter_rewritable_modules)rJ  Z	seen_somefnZis_simple_module
is_packagemodule_namer   package_nameZnew_package_filespartsZnew_fnr>   r>   r?   rQ  8  s.     
rQ  c                   @   s  e Zd ZdZeejddG dd dZG dd dej	Z
dd	eee dd
ddZeedddZeee dddZeg df ddddZddddZddddZedddZeee d dddZdmee eej dddd Zeed!d"d#Z e!d dd$d%Z"d&dd'd(d)Z#e$dd*d dd+d,d-Z%e&e dd.d/d0Z'e&e dd.d1d2Z(ddd3d4Z)ee eee d5d6d7Z*dnee e+dd8d9d:Z,e$dd;e-d< dd=d>Z.ddd?d@Z/dddAdBZ0dddCdDZ1eddEdFdGZ2ee ddHdIZ3doee e+dd8dJdKZ4e5e6ddLdMdNZ7eeddOdPdQZ8edRdSdTZ9eee:eee f dUdVdWZ;edRdXdYZ<eeeeee  dZd[d\Z=eee d]d^d_Z>e?d`fee+dadbdcZ@dpedRdddeZAdqedRdfdgZBeddhdidjZCdddkdlZDdS )rr   a  Access to configuration values, pluginmanager and plugin hooks.

    :param PytestPluginManager pluginmanager:
        A pytest PluginManager.

    :param InvocationParams invocation_params:
        Object containing parameters regarding the :func:`pytest.main`
        invocation.
    T)frozenc                   @   sj   e Zd ZU dZeedf ed< eee	ee
f   ed< eed< ee eee	ee
f   edddd	ZdS )
zConfig.InvocationParamsa  Holds parameters passed during :func:`pytest.main`.

        The object attributes are read-only.

        .. versionadded:: 5.1

        .. note::

            Note that the environment variable ``PYTEST_ADDOPTS`` and the ``addopts``
            ini option are handled by pytest, not being included in the ``args`` attribute.

            Plugins accessing ``InvocationParams`` must be aware of that.
        .rW   rX   r   N)rW   rX   r   rC   c                C   s2   t | dt| t | d| t | d| d S )NrW   rX   r   )object__setattr__tuple)rG   rW   rX   r   r>   r>   r?   rF     s    z Config.InvocationParams.__init__)r7   r8   r9   r:   r   rO   __annotations__r   r   r   rA  r   r   rF   r>   r>   r>   r?   r     s   
r   c                   @   s(   e Zd ZdZe Ze Ze ZdS )zConfig.ArgsSourcezSIndicates the source of the test arguments.

        .. versionadded:: 7.2
        N)	r7   r8   r9   r:   enumautoARGSINCOVATION_DIR	TESTPATHSr>   r>   r>   r?   
ArgsSource  s   ra  Nr   )r   r   rC   c                C   s  ddl m}m} |d u r,| jdd t d}t | _|| _	|}|d| d| d| j
dd	| _|| _t | _| j| _dd
lm} | jjjd| _|| jj| _i | _d| _i | _g | _| j| d d| _| jjjt| j| jdd tj j!| _"g | _#t$rddl%m&} d | _'d S )Nr   )ParserFILE_OR_DIRr>   r   z%(prog)s [options] [z] [z] [...]T)usageZ
processoptZ	_ispytest)PathAwareHookProxyr^   ZpytestconfigF)parserr   r   r   )Cache)(
argparsingrb  rc  r   r   r   rB  rC  optionr   _processopt_parserr   r+   stash_storecompatre  r   r   r   ri   	_inicache_override_ini	_opt2dest_cleanupr   r   Zpytest_addoptionr   r   r   ra  r^  args_sourcerW   r   Z_pytest.cacheproviderrg  cache)rG   r   r   rb  rc  _are  rg  r>   r>   r?   rF     sB    


zConfig.__init__rJ   c                 C   s   | j S )znThe path to the :ref:`rootdir <rootdir>`.

        :type: pathlib.Path

        .. versionadded:: 6.1
        )	_rootpathrL   r>   r>   r?   r     s    zConfig.rootpathc                 C   s   | j S )zThe path to the :ref:`configfile <configfiles>`.

        :type: Optional[pathlib.Path]

        .. versionadded:: 6.1
        )_inipathrL   r>   r>   r?   inipath  s    zConfig.inipath)funcrC   c                 C   s   | j | dS )zxAdd a function to be called when the config object gets out of
        use (usually coinciding with pytest_unconfigure).N)rr  r   )rG   ry  r>   r>   r?   add_cleanup  s    zConfig.add_cleanupc                 C   s\   | j r
J d| _ t 0 td | jjjt| dd W d    n1 sN0    Y  d S )NTdefaultr]   r   )r   r   catch_warningssimplefilterri   r   r   r   rL   r>   r>   r?   _do_configure  s
    


zConfig._do_configurec                 C   s@   | j r$d| _ | jj| d g | jj_| jr<| j }|  q$d S )NFr]   )r   ri   Zpytest_unconfigurer   Z_call_historyrr  pop)rG   Zfinr>   r>   r?   rj     s    

zConfig._ensure_unconfigurec                 C   s   | j d}|jS )Nterminalreporter)r   r   Z_tw)rG   r  r>   r>   r?   get_terminal_writer!  s    zConfig.get_terminal_writer)r   rW   rC   c                 C   s   z|  | W nx ty   t| jdds2d|v rHddlm} ||  n8t| jddsfd|v sfd|v r| j   t	j
d	  Y n0 | S )
NversionFz	--versionr   )showversionhelpz--helpz-hz8
NOTE: displaying only minimal help due to UsageError.

)parser   r   ri  Z_pytest.helpconfigr  rk  Z
_getparser
print_helpra   rr   r   )rG   r   rW   r  r>   r>   r?   r   '  s$    
zConfig.pytest_cmdline_parse)rB   ri  rC   c                 C   s|   |rt |ddrd}nd}|jdt |dd|d}| jj||d}t|sxt|d	D ]}tj	d
|  tj
  qXd S )NZ	fulltraceFlongnativeT
showlocals)Zfuncargsr  r[   )excreprrB   r_   zINTERNALERROR> %s
)r   rf   ri   Zpytest_internalerroranyrO   rS   ra   rb   r   rs   )rG   rB   ri  r[   r  resrc   r>   r>   r?   notify_exception@  s    zConfig.notify_exception)nodeidrC   c                 C   s*   | j j| jkr&| j| }t| j j|}|S rD   )r   r   r   r'   )rG   r  fullpathr>   r>   r?   cwd_relative_nodeidR  s    
zConfig.cwd_relative_nodeidc                 C   sB   t |}|jj| |j|dd |jjD ]}|j| q,|S )z$Constructor usable for subprocesses.Faddopts)r   ri  __dict__updater  rX   r   r   )clsoption_dictrW   r^   r  r>   r>   r?   fromdictargsY  s    zConfig.fromdictargsr0   )r.  rC   c                 C   sL   |j |j D ]}|j| j|< qt|drHt| j|jsHt| j|j|j d S )Nr{  )_short_opts
_long_optsdestrq  r(  ri  setattrr{  )rG   r.  r   r>   r>   r?   rj  c  s
    
zConfig._processopt)r   )early_configrC   c                 C   s   | j j|j|jd d S r  )r   r  known_args_namespacer   )rG   r  r>   r>   r?   pytest_load_initial_conftestsk  s    z$Config.pytest_load_initial_conftests)rW   rC   c                 C   s   | j j|t| jd\}}t|j|j| |jp2d | d\}}}|| _|| _	|| _
t| j| j jd< t| j| j jd< | j ddd | j dd	 | j jd
ddg d |jpd| _d S )Nr   )Zrootdir_cmd_argr^   rootdirZinifiler  zExtra command line optionsrW   
minversionz!Minimally required pytest versionrequired_pluginsz.Plugins that must be present for pytest to run)r   r{  r>   )rk  parse_known_and_unknown_argscopyri  r   Zinifilenamer  r  rv  rw  inicfgrO   r   Z
extra_inforx  ZaddiniZoverride_inirp  )rG   rW   nsunknown_argsr   rx  r  r>   r>   r?   _initiniq  s.    
zConfig._initinic                 C   sl   | j |\}}t|dd}|dkr^ddl}z|j| }W n tyR   d}Y n0 | | | | dS )zInstall the PEP 302 import hook if using assertion rewriting.

        Needs to parse the --assert=<mode> option from the commandline
        and find all the installed plugins to mark them for rewriting
        by the importhook.
        Z
assertmodeplainZrewriter   N)	rk  r  r   r   r   Zinstall_importhookSystemError_mark_plugins_for_rewrite_warn_about_missing_assertion)rG   rW   r  r  r   r   ri   r>   r>   r?   _consider_importhook  s    

zConfig._consider_importhookc                 C   sF   || j _tjdrdS dd t D }t|D ]}|| q2dS )zGiven an importhook, mark for rewrite any top-level
        modules or packages in the distribution package for
        all pytest plugins.PYTEST_DISABLE_PLUGIN_AUTOLOADNc                 s   s:   | ]2}t d d |jD r|jp"g D ]}t|V  q$qdS )c                 s   s   | ]}|j d kV  qdS )r8  N)group)r   epr>   r>   r?   	<genexpr>  r   z=Config._mark_plugins_for_rewrite.<locals>.<genexpr>.<genexpr>N)r  entry_pointsfilesrO   )r   distfiler>   r>   r?   r    s   z3Config._mark_plugins_for_rewrite.<locals>.<genexpr>)	r   r   rT   r   r   r#   distributionsrQ  r<  )rG   ri   rJ  r   r>   r>   r?   r    s    z Config._mark_plugins_for_rewrite)rW   viarC   c                 C   s8   || j _z"| j j|t| jd W | j `n| j `0 |S )zValidate known args.r  )rk  Z_config_source_hintr  r  ri  )rG   rW   r  r>   r>   r?   _validate_args  s    zConfig._validate_args)rW   r  rC   c              
   C   s  |r8t jdd}t|r8| t|d| |d d < | | |rd| | dd| |d d < | j	j
|t| jd| _|   | | | jj|dd t jd	s| jd
 | j  | j	j
|t| jd| _|   |   | jjr| jtjjdd | jjd u r6| jd ur6t| jj}|| j_z| jj | || j	d W nX t!y } z>| jj"st| jj#r| jt$d|j% dd n W Y d }~n
d }~0 0 d S )NZPYTEST_ADDOPTSr9  zvia PYTEST_ADDOPTSr  zvia addopts configr  Fr   r  r8  r3   
stacklevel)r  rW   rf  z"could not load initial conftests: )&rT   r   r   r*  r  shlexrS   r  getinirk  parse_known_argsr  ri  r  _checkversionr  r   r   r=  r5  _validate_plugins_warn_about_skipped_pluginsstrictissue_config_time_warningr   r   ZSTRICT_OPTIONr  rx  rO   r   ri   r  r@   r  r  r,   rA   )rG   rW   r  Zenv_addoptsr  rl   r>   r>   r?   	_preparse  sV    






zConfig._preparse)r   )NNNc                 c   s   d V  |    d S rD   )_validate_config_optionsrL   r>   r>   r?   pytest_collection  s    zConfig.pytest_collectionc                 C   sn   dd l }| jdd }|rjddlm} t|ts@|d| j ||||j	krj|d| j||j	f d S )Nr   r  Versionz'%s: 'minversion' must be a single valuez6%s: 'minversion' requires pytest-%s, actual pytest-%s')
r1   r  r   packaging.versionr  r   rO   r   rx  __version__)rG   r1   Zminverr  r>   r>   r?   r    s"    
zConfig._checkversionc                 C   s(   t |  D ]}| d| d qd S )NzUnknown config option: r_   )sorted_get_unknown_ini_keys_warn_or_fail_if_strict)rG   keyr>   r>   r?   r    s    zConfig._validate_config_optionsc           
   	   C   s   t | d}|sd S ddlm} ddlm}m} | j }dd |D }g }|D ]l}z||}	W n  |y   |	| Y qRY n0 |	j
|vr|	| qR|	jj|||	j
 ddsR|	| qR|rtd	d
|d S )Nr  r   r  )InvalidRequirementRequirementc                 S   s   i | ]\}}|j |jqS r>   )project_namer  )r   r   r  r>   r>   r?   
<dictcomp>"  r   z,Config._validate_plugins.<locals>.<dictcomp>T)prereleaseszMissing required plugins: {}r   )r  r  r  r  Zpackaging.requirementsr  r  r   Zlist_plugin_distinfor   r   	specifiercontainsr   rK   r   )
rG   r  r  r  r  Zplugin_infoZplugin_dist_infoZmissing_pluginsZrequired_pluginreqr>   r>   r?   r    s0    



zConfig._validate_plugins)r   rC   c                 C   s&   | j jrt|| jt|dd d S )Nr4   r  )r  Zstrict_configr   r  r,   )rG   r   r>   r>   r?   r  8  s    zConfig._warn_or_fail_if_strictc                    s   | j j  fdd| jD S )Nc                    s   g | ]}| vr|qS r>   r>   )r   r   Zparser_inicfgr>   r?   
<listcomp>@  r   z0Config._get_unknown_ini_keys.<locals>.<listcomp>)rk  _inidictr  rL   r>   r  r?   r  >  s    zConfig._get_unknown_ini_keysc                 C   s
  | j g ksJ d| jjjt| jdd | j||d | jj| |d d| j_	zt
jj}| jj|| j| jd}|s| jj| jkrt
jj}| d}| jjr|}n&g }|D ]}|ttj|dd	 q|st
jj}t| jjg}|| _ || _W n ty   Y n0 d S )
Nz:can only parse cmdline args at most once per Config object)r   r   r  )r^   rW   Tr  r  )	recursive)rW   ri   Zpytest_addhooksr   r   r   r  Zpytest_cmdline_preparserk  Zafter_preparser   ra  r^  Zparse_setoptionri  r   r   r   r`  r  r  r  extendr  r  iglobr_  rO   rs  r   )rG   rW   r  sourcer  rA   r>   r>   r?   r  B  s>    



zConfig.parse)warningr  rC   c                 C   s   | j drdS | jjpg }| d}tjdd8}tdt| t	|| tj
||d W d   n1 sp0    Y  |rt|d }|jj|j|jjf}| jjjt|d	 d
d|dd dS )a   Issue and handle a warning during the "configure" stage.

        During ``pytest_configure`` we can't capture warnings using the ``catch_warnings_for_item``
        function because it is not possible to have hookwrappers around ``pytest_configure``.

        This function is mainly intended for plugins that need to issue warnings during
        ``pytest_configure`` (or similar stages).

        :param warning: The warning instance.
        :param stacklevel: stacklevel forwarded to warnings.warn.
        r   NfilterwarningsT)recordalwaysr  r   r   r^   r9  )Zwarning_messagewhenr  locationr   )r   r:  r  Zpythonwarningsr  r   r|  r}  r   apply_warning_filtersr   ra   	_getframef_codeco_filenamef_linenoco_nameri   Zpytest_warning_recordedr   r   )rG   r  r  cmdline_filtersconfig_filtersrecordsframer  r>   r>   r?   r  e  s&    

,z Config.issue_config_time_warning)r   rc   rC   c                 C   s&   |  |}t|tsJ || dS )zAdd a line to an ini-file option. The option must have been
        declared but might not yet be set in which case the line becomes
        the first line in its value.N)r  r   r   r   )rG   r   rc   r  r>   r>   r?   r     s    
zConfig.addinivalue_liner   c                 C   s<   z| j | W S  ty6   | | | j |< }| Y S 0 dS )a  Return configuration value from an :ref:`ini file <configfiles>`.

        If the specified name hasn't been registered through a prior
        :func:`parser.addini <pytest.Parser.addini>` call (usually from a
        plugin), a ValueError is raised.
        N)ro  r  _getini)rG   r   valr>   r>   r?   r    s
    zConfig.getini)r   r   valuec                 C   s   d| }t ||d S )Nzunknown configuration type: )rk   )rG   r   r   r  rp   r>   r>   r?   _getini_unknown_type  s    
zConfig._getini_unknown_typec           	   
      s  z| j j| \}}}W n4 tyJ } ztd||W Y d }~n
d }~0 0 | |}|d u rz| j| }W q ty   |d ur| Y S |d u rY dS g  Y S 0 n|}|dkr| jd usJ | jj t|t	rt
|n|} fdd|D S |dkrt|t	rt
|S |S |dkrNt|t	rHdd td	d
 |dD S |S nD|dkrhtt	| S |dkrv|S |d u r|S | |||S d S )Nzunknown configuration value: r9  pathsc                    s   g | ]} | qS r>   r>   )r   r  Zdpr>   r?   r    r   z"Config._getini.<locals>.<listcomp>rW   Zlinelistc                 S   s   g | ]}|r|qS r>   r>   )r   tr>   r>   r?   r    r   c                 S   s   |   S rD   r,  )r  r>   r>   r?   <lambda>  r   z Config._getini.<locals>.<lambda>r_   r   string)rk  r  r  rk   _get_override_ini_valuer  rx  r   r   rO   r  rS   map
_strtoboolr,  r  )	rG   r   descriptionr   r{  rl   Zoverride_valuer  Zinput_valuesr>   r  r?   r    sB    &





zConfig._getini)r   rA   r   rC   c           	      C   s   z | j ||| d|\}}W n ty4   Y d S 0 |jd usDJ t|jj}g }|D ]>}t|tj	rrt|}n|
dtj}t|| }|| qX|S )Nr	  rK  )r   r  	getoptionr  r3  r   r   r   rT   r   r   rU   r&   r   )	rG   r   rA   r   r  ZrelrootsmodpathvaluesZrelrootr>   r>   r?   _getconftest_pathlist  s     
zConfig._getconftest_pathlistr   c                 C   sj   d }| j D ]Z}z|dd\}}W n4 tyV } ztd||W Y d }~q
d }~0 0 ||kr
|}q
|S )Nr   r   z9-o/--override-ini expects option=value style (got: {!r}).)rp  rS   rk   r   rK   )rG   r   r  Z
ini_configr  Zuser_ini_valuerl   r>   r>   r?   r    s    
zConfig._get_override_ini_valueF)r   skipc              
   C   s   | j ||}z&t| j|}|du r0|r0t||W S  ty } zR|tur\|W  Y d}~S |rzddl}|d|d td||W Y d}~n
d}~0 0 dS )ai  Return command line option value.

        :param name: Name of the option.  You may also specify
            the literal ``--OPT`` option instead of the "dest" option name.
        :param default: Default value if no option of that name exists.
        :param skip: If True, raise pytest.skip if option does not exists
            or has a None value.
        Nr   zno z option foundzno option named )	rq  r   r   ri  r   notsetr1   r  rk   )rG   r   r{  r  r  rl   r1   r>   r>   r?   r    s    	zConfig.getoptionc                 C   s
   |  |S )z$Deprecated, use getoption() instead.r  rG   r   rA   r>   r>   r?   getvalue  s    zConfig.getvaluec                 C   s   | j |ddS )z-Deprecated, use getoption(skip=True) instead.T)r  r  r  r>   r>   r?   getvalueorskip  s    zConfig.getvalueorskip)r   rC   c                 C   s.   t  s*|dkrd}nd}| jt|dd d S )Nr  zRASSERTIONS ARE NOT EXECUTED and FAILING TESTS WILL PASS.  Are you using python -O?zassertions not in test modules or plugins will be ignored because assert statements are not executed by the underlying Python interpreter (are you using python -O?)
r4   r  )_assertion_supportedr  r,   )rG   r   Zwarning_textr>   r>   r?   r  !  s    z$Config._warn_about_missing_assertionc                 C   s4   | j jD ]&\}}| jtd|d| dd qd S )Nzskipped plugin : r3   r  )r   r   r  r,   )rG   rT  rp   r>   r>   r?   r  6  s
    z"Config._warn_about_skipped_plugins)N)T)T)N)N)Er7   r8   r9   r:   r"   dataclasses	dataclassr   r\  Enumra  r   r   rF   propertyr   r   rx  r   rz  r~  rj   r!   r  r   rO   r   r   r   rB  rC  r  r  classmethodr  rj  hookimplr  r   r  r  r  r  r   r  r   r  r  r  r  r  r  r  Warningintr  r   r  r   r  r  r  r  r   r  r  r  r  r  r>   r>   r>   r?   r   y  sz   

!C			 	8 ##7
c                   C   s*   zds
J W n t y    Y dS 0 dS d S )NFT)AssertionErrorr>   r>   r>   r?   r  >  s
    r  )r^   r  rC   c                 C   sZ   t |d}| jjdkrd|_n| jjdkr0d|_| jjdkrDd|_n| jjdkrVd|_|S )zCreate a TerminalWriter instance configured according to the options
    in the config object.

    Every code which requires a TerminalWriter object and has access to a
    config object should use this function.
    )r  yesTnoF)r!   ri  colorZ	hasmarkupZcode_highlight)r^   r  rn   r>   r>   r?   create_terminal_writerG  s    	
r  )r  rC   c                 C   s2   |   } | dv rdS | dv r dS td| dS )a  Convert a string representation of truth to True or False.

    True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values
    are 'n', 'no', 'f', 'false', 'off', and '0'.  Raises ValueError if
    'val' is anything else.

    .. note:: Copied from distutils.util.
    )yr  r  trueon1T)r-  r  ffalseoff0Fzinvalid truth value N)lowerrk   )r  r>   r>   r?   r  _  s    	r  2   )maxsizezwarnings._ActionKind)r/  escaperC   c             
   C   s  d}t d|  d}| d}t|dkrXd}t dt| d| d	}t|j|d
t|dk rp|d qXdd |D \}}}	}
}zt|}W n: tjy } z t|jt	|d
W Y d}~n
d}~0 0 zt
|	}W n8 ty   t }|jdd}t|j|d
Y n0 |r.|r.t|}|
rH|rHt|
d }
|rzt|}|dk rjtdW nB ty } z(t|jd|d| d
W Y d}~n
d}~0 0 nd}||||
|fS )zParse a warnings filter string.

    This is copied from warnings._setoption with the following changes:

    * Does not apply the filter.
    * Escaping is optional.
    * Raises UsageError so we get nice error messages on failure.
    TzF        while parsing the following warning configuration:

          z8

        This error occurred:

        {error}
        :r6   zJhttps://docs.python.org/3/library/warnings.html#describing-warning-filtersz            Too many fields (z), expected at most 5 separated by colons:

              action:message:category:module:line

            For more information please consult: z
            )errorr9  c                 s   s   | ]}|  V  qd S rD   r  )r   sr>   r>   r?   r    r   z'parse_warning_filter.<locals>.<genexpr>Nr  )r[   z\Zr   znumber is negativezinvalid lineno r  )r   rS   r*  r   rK   r   r   
_getaction_OptionErrorrO   _resolve_warning_categoryrN   r   Zfrom_currentrf   rer  r  rk   )r/  r  __tracebackhide__Zerror_templaterV  Zdoc_urlr!  Zaction_r   Z	category_moduleZlineno_actionrl   categoryrm   Zexception_textlinenor>   r>   r?   parse_warning_filterq  s\    
	*

r,  )r*  rC   c                 C   sr   d}| st S d| vr"ddl}| }n | d\}}}t|dd|g}t||}t|t sdt| dttt  |S )z
    Copied from warnings._getcategory, but changed so it lets exceptions (specially ImportErrors)
    propagate so we can get access to their tracebacks (#9218).
    T.r   Nz is not a Warning subclass)	r  builtins
rpartitionr>  r   
issubclassr   r	   r   )r*  r'  r   klassr(  r   catr>   r>   r?   r%    s    

r%  )r  r  rC   c                 C   s<   | D ]}t jt|dd  q|D ]}t jt|dd  q dS )z8Applies pytest-configured filters to the warnings moduleF)r  TN)r   r  r,  )r  r  r/  r>   r>   r?   r    s    r  )NN)NN)NN)N)~r:   rB  collections.abcrF  r  r  r\  r  r   rT   r&  r  ra   r   r   	functoolsr   pathlibr   textwrapr   r   r   typingr   r   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   Zpluggyr   r   r   Z_pytest._coder   Z_pytest.deprecatedZ_pytest.hookspec
exceptionsr   r   Z	findpathsr   r   r    Z_pytest._ior!   Z_pytest.compatr"   r#   Z_pytest.outcomesr$   r%   Z_pytest.pathlibr&   r'   r(   r)   r*   Z_pytest.stashr+   Z_pytest.warning_typesr,   r-   Z_pytest._code.coder.   Z_pytest.terminalr/   rh  r0   rX  rA  r  r   IntEnumr2   rN   r@   _codeZTracebackEntryr   rV   rO   r  rq   r{   r|   r   r   r1  version_infor   r   r;  r"  r   r   r`   r   r   r   r   r6  r  rH  r   rQ  r   r  r  r  r  r,  r%  r  r>   r>   r>   r?   <module>   sX  
  
0

  
   	

    A     I
 G