o
    h                     @   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,l@mFZF dd-lGmHZH dd.lImJZJ dd/lImKZK e'r_dd0lLmMZM dd1lNmOZO dd2lPmQZQ eRZS	 e*d3ZTe+d3ZUe;G d4d5 d5ejVZWG d6d7 d7eXZYd8e.jZj[d9e\fd:d;Z]		dd<e!e(e e^ d=f  d>e!e"e(e^eSf   d9e(e_eWf fd?d@Z`d9e_fdAdBZaG dCdD dDZbdEe^dFe^d9e^fdGdHZcdEe^dFe^d9e^fdIdJZddKZeeedLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]d^d_d`dadbdcgejfddkrdedfgng dgR  ZgehegZieijdh eijdi 		dd<e!e e^  d>e!e"e(e^eSf   d9djfdkdlZkddndoZl		dd<e!e(e e^ d=f  d>e!e"e(e^eSf   d9djfdpdqZmdEed9efdrdsZndtedue^dve%e^dwf d9ee^e\f fdxdyZoe;G dzdm dme,Zpd{e(dejqe^e"e^ f d9e e^ fd|d}Zrd~e^d9dfddZsG dd dZtet Zudee^ d9ee^ fddZve;G ddj djZwd9e\fddZx	ddewde!e$ d9e9fddZyde^d9e\fddZzeddde^de\d9e%de^e&e{ e^e_f fddZ|de^d9e&e{ fddZ}dee^ dee^ d9df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)safe_exists)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__OKTESTS_FAILEDINTERRUPTEDINTERNAL_ERRORUSAGE_ERRORNO_TESTS_COLLECTED rB   rB   M/var/www/html/ai/venv/lib/python3.10/site-packages/_pytest/config/__init__.pyr3   U   s    r3   c                       sF   e Zd Zdedeee eef ddf fddZde	fddZ
  ZS )	ConftestImportFailurepathexcinforeturnNc                    s   t  || || _|| _d S N)super__init__rE   rF   )selfrE   rF   	__class__rB   rC   rJ   m   s   
zConftestImportFailure.__init__c                 C   s   d | jd j| jd | jS )Nz{}: {} (from {})r   r   )formatrF   r8   rE   rK   rB   rB   rC   __str__v   s   zConftestImportFailure.__str__)r8   r9   r:   r   r   r   	Exceptionr   rJ   strrP   __classcell__rB   rB   rL   rC   rD   l   s    	rD   entryrG   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    rR   rE   splitossep)rT   rB   rB   rC   ,filter_traceback_for_conftest_import_failure|   s   rY   argszos.PathLike[str]pluginsc              
   C   sh  zzt | |}W nV ty^ } zJt|j}ttj}|jd|j	 ddd |j
t|_
|j
r8|jdddn| }t|}| D ]}|j| dd qDtjW  Y d}~W S d}~ww z$|jj|d	}	zt|	W W |  W S  ty   |	 Y W |  W S w |  w  ty } zttj}|jD ]}
|jd
|
 ddd qtjW  Y d}~S d}~ww )aL  Perform an in-process test run.

    :param args:
        List of command line arguments. If `None` or not given, defaults to reading
        arguments directly from the process command line (:data:`sys.argv`).
    :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: 
)_prepareconfigrD   r   from_exc_inforF   r!   sysstderrlinerE   	tracebackfilterrY   getreprexconlyrR   
splitlinesrstripr3   r@   hookpytest_cmdline_main_ensure_unconfigure
ValueErrorr   rZ   )rZ   r[   ra   eexc_infotwexc_reprformatted_tbrg   retmsgrB   rB   rC   main   sN   




ry   c                  C   sN   zt  } tj  | W S  ty&   ttjtj}t	|tj
  Y dS w )zoThe CLI entry point of pytest.

    This function is not meant for programmable use; use `main()` instead.
    r   )ry   re   stdoutflushBrokenPipeErrorrW   opendevnullO_WRONLYdup2fileno)coder~   rB   rB   rC   console_main   s   
r   c                   @   s   e Zd ZeeZdS )cmdlineN)r8   r9   r:   staticmethodry   rB   rB   rB   rC   r          r   rE   optnamec                 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: rW   rE   isdirr   rE   r   rB   rB   rC   filename_arg      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   rB   rB   rC   directory_arg   r   r   )markry   runnerfixtures
helpconfigpythonterminal	debuggingunittestcaptureskipping
legacypathtmpdirmonkeypatchrecwarnpastebinnose	assertionjunitxmldoctestcacheproviderfreeze_support	setuponly	setupplanstepwisewarningsloggingreportspython_path)r5      unraisableexceptionthreadexceptionfaulthandlerpytesterpytester_assertionsConfigc                 C   sT   t  }t|tj| p
d|t dd}| d ur|j| dd tD ]}|| q |S )NrB   rZ   r[   dirinvocation_paramsTexclude_only)PytestPluginManagerr   InvocationParamsr   cwdconsider_preparsedefault_pluginsimport_plugin)rZ   r[   pluginmanagerra   specrB   rB   rC   
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   rB   rB   rB   rC   get_plugin_manager)  s   r   c                 C   s   | d u rt jdd  } nt| tjrt| g} nt| ts*d}t|| t	| t
| |}|j}z"|rJ|D ]}t|trD|| q7|| q7|jj|| d}|W S  ty`   |   w )Nr   zG`args` parameter expected to be a list of strings, got: {!r} (type: {}))r   rZ   )re   argv
isinstancerW   PathLikefspathlist	TypeErrorrN   typer   r   rR   consider_pluginargregisterrn   pytest_cmdline_parseBaseExceptionrp   )rZ   r[   rx   ra   r   pluginrB   rB   rC   rc   4  s0   


rc   c                 C   s   |   r| jS | S )z<Get the directory of a path - itself if already a directory.)is_fileparent)rE   rB   rB   rC   _get_directoryT  s   r   method	hook_type	opt_names.c           
      C   s   t r	t| s	J dd t| dg D }g }i }|D ]0}t| |t}|tur5|| d|  d||< q||v rF|| d d||< qd||< q|red|}tjj	j
|| j|d	}	ttt| |	 |S )
Nc                 S   s   h | ]}|j qS rB   name).0mrB   rB   rC   	<setcomp>d  s    z)_get_legacy_hook_marks.<locals>.<setcomp>
pytestmark=Tz=TrueF, )r   fullname	hook_opts)r   inspect	isroutinegetattrAttributeErrorappendjoin_pytest
deprecatedHOOK_LEGACY_MARKINGrN   r:   r.   r	   r   )
r   r   r   known_marks	must_warnoptsopt_nameopt_attrr   messagerB   rB   rC   _get_legacy_hook_marks\  s.   



r   c                       s@  e Zd ZdZdD fddZdedef fdd	Zdef fd
dZ	dEdede	e de	e f fddZ
defddZdedefddZdFddZdeeeef  dededede	e deeef ddfddZdedefdd Zd!edeeef deddfd"d#Zdedeeef dedeej fd$d%Zdededeeef dedeejef f
d&d'Zd(edeeef dedejfd)d*Zd+ejd(eddfd,d-Zd.d/dee d0eddfd1d2Zd3eddfd4d5Zd6ejddfd7d8Z dDd9d:Z!d+ejddfd;d<Z"d=edejeee f ddfd>d?Z#dGd@edAeddfdBdCZ$  Z%S )Hr   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.
    rG   Nc                    s   dd l }t d t | _i | _d | _d| _tdt	| _	t | _
g | _| |j | |  tjdretj}t|dd}ztt| |jd|d	}W n	 tyX   Y nw | jj|j |   |j  | _!d| _"d S )
Nr   r2   F   PYTEST_DEBUGencodingutf8r   )mode	bufferingr   )#_pytest.assertionrI   rJ   set_conftest_plugins_dirpath2confmods_confcutdir_noconftestr   r   _duplicatepathsskipped_pluginsadd_hookspecshookspecr   rW   environgetre   rf   r   r}   dupr   r   rQ   traceroot	setwriterwriteenable_tracingr   DummyRewriteHookrewrite_hook_configured)rK   r   errr   rL   rB   rC   rJ     s8   


zPytestPluginManager.__init__r   r   c                    sX   | dsd S |dkrd S t ||}|d ur|S t||}t|s&d S t|ddS )Npytest_pytest_pluginsimpl)tryfirsttrylastoptionalhookhookwrapper)
startswithrI   parse_hookimpl_optsr   r   r   r   )rK   r   r   r   r   rL   rB   rC   r    s   


z'PytestPluginManager.parse_hookimpl_optsc                    s:   t  ||}|d u rt||}|drt|dd}|S )Nr	  r   )firstresulthistoric)rI   parse_hookspec_optsr   r  r   )rK   module_or_classr   r   r   rL   rB   rC   r    s   

z'PytestPluginManager.parse_hookspec_optsc              	      sp   |t jjv rttd|dd d S t 	||}|r6| j
jjt|| dd t|tjr6| | |S )NzQ{} plugin has been merged into the core, please remove it from your requirements._-)r   managerkwargs)r   r   DEPRECATED_EXTERNAL_PLUGINSr   warnr-   rN   replacerI   r   rn   pytest_plugin_registeredcall_historicdictr   types
ModuleTypeconsider_module)rK   r   r   rw   rL   rB   rC   r     s$   


zPytestPluginManager.registerc                 C   s   |  |}|S rH   )
get_plugin)rK   r   r   rB   rB   rC   	getplugin  s   
zPytestPluginManager.getpluginc                 C   s   t | |S )z:Return whether a plugin with the given name is registered.)boolr$  )rK   r   rB   rB   rC   	hasplugin     zPytestPluginManager.haspluginra   r   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  )rK   ra   rB   rB   rC   pytest_configure  s   
z$PytestPluginManager.pytest_configurerZ   pyargs
noconftestrootpath
confcutdir
importmodec                 C   s   t  }|rt|| nd| _|| _|| _d}|D ](}	t|	}
|
d}|dkr.|
d| }
t||
 }t|rA| 	||| d}q|sM| 	||| dS 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   r&   r   r   _using_pyargsrR   findr+   _try_load_conftest)rK   rZ   r-  r.  r/  r0  r1  currentfoundanchorintitial_pathrE   ianchorrB   rB   rC   _set_initial_conftests  s$   
z*PytestPluginManager._set_initial_conftestsrE   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)rK   rE   rB   rB   rC   _is_in_confcutdir8  s   
z%PytestPluginManager._is_in_confcutdirr:  c                 C   sD   |  ||| | r|dD ]}| r|  ||| qd S d S )Nztest*)_getconftestmodulesis_dirglob)rK   r:  r1  r/  xrB   rB   rC   r5  A  s   z&PytestPluginManager._try_load_conftestc           
      C   s   | j rg S | |}| j|}|d ur|S g }t|g|jR D ]}| |r<|d }| r<| |||}	|	|	 q!|| j|< |S )Nzconftest.py)
r   r   r   r   reversedr<  r=  r   _importconftestr   )
rK   rE   r1  r/  	directoryexisting_clistclistr   conftestpathmodrB   rB   rC   r>  K  s    



z'PytestPluginManager._getconftestmodulesc              	   C   sL   | j |||d}t|D ]}z
|t||fW   S  ty!   Y qw t|)N)r/  )r>  rB  r   r   KeyError)rK   r   rE   r1  r/  modulesrH  rB   rB   rC   _rget_with_confmodf  s   z&PytestPluginManager._rget_with_confmodrG  c              
   C   s  |  t|}|d urttj|S t|}|d u rt|j z	t|||d}W n! t	yH } z|j
d us6J t|||j
f}t|||d }~ww | || | j| |j}	|	| jv r{| j D ]\}
}|	|
jv so|
|	krz||vsuJ || qb| d| | | |S )N)r   r  zloading conftestmodule )r$  rR   r	   r!  r"  r*   _ensure_removed_sysmodulestemr(   rQ   __traceback__r   rD   _check_non_top_pytest_pluginsr   addr   r   itemsr<  r   r   consider_conftest)rK   rG  r1  r/  existingpkgpathrH  rr   rs   dirpathrE   modsrB   rB   rC   rC  u  s4   



z#PytestPluginManager._importconftestrH  c                 C   s@   t |dr| jr| jsd}t||| jdd d S d S d S 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)pytrace)hasattrr  r3  r$   rN   r   )rK   rH  rG  rx   rB   rB   rC   rO    s   	z1PytestPluginManager._check_non_top_pytest_pluginsFr   r   c                C   s   d}t |}||k rU|| }|d7 }t|trO|dkr1z|| }W n
 ty+   Y dS w |d7 }n|dr=|dd }nq| }|rJ|dsJq| | ||k s
dS dS )r)  r   r   z-pNr4   no:)lenr   rR   
IndexErrorr  stripr   )rK   rZ   r   r9  noptpargrB   rB   rC   r     s*   



z%PytestPluginManager.consider_preparseargc                 C   s   | dr8|dd }|tv rtd| |dkr#| d | d | | | ds6| d|  dS dS |}| j|d	du rG| j|= | ds]| jd| d	du r]| jd| = | j|d
d dS )r)  rY  r5   Nzplugin %s cannot be disabledr   r   pytest_stepwiser	  r2  T)consider_entry_points)r  essential_pluginsr   set_blocked_name2pluginr   r   )rK   r`  r   rB   rB   rC   r     s$   





z&PytestPluginManager.consider_pluginargconftestmodulec                 C   s   | j ||jd dS )r)  r   N)r   __file__)rK   rf  rB   rB   rC   rR    s   z%PytestPluginManager.consider_conftestc                 C   s   |  tjd dS )r)  PYTEST_PLUGINSN)_import_plugin_specsrW   r   r   rO   rB   rB   rC   consider_env     z PytestPluginManager.consider_envc                 C   s   |  t|dg  dS )r)  r
  N)ri  r   )rK   rH  rB   rB   rC   r#    rk  z#PytestPluginManager.consider_moduler   c                 C   s    t |}|D ]}| | qd S rH   )_get_plugin_specs_as_listr   )rK   r   r[   import_specrB   rB   rC   ri    s   z(PytestPluginManager._import_plugin_specsmodnamerb  c              
   C   s
  t |tsJ d| | |s| |durdS |tv r!d| n|}| j| |r6| jd|d}|r6dS zt| W n; t	yZ } zt	d| d|j
d  |j|d}~w tyw } z| j||jpid	f W Y d}~dS d}~ww 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   rR   
is_blockedr$  builtin_pluginsr  mark_rewriteload_setuptools_entrypoints
__import__ImportErrorrZ   with_tracebackrN  r%   r   r   rx   re   rJ  r   )rK   rn  rb  
importspecloadedrr   rH  rB   rB   rC   r     s4   

$
z!PytestPluginManager.import_pluginrG   NrH   )ra   r   rG   N)F)&r8   r9   r:   r;   rJ   _PluggyPluginrR   r  r  r   r   r%  r&  r'  r,  r   r   r   r)   r;  r=  r5  r!  r"  r>  r   r   rK  rC  rO  r   r   rR  rj  r#  ri  r   rS   rB   rB   rL   rC   r   |  s    5


%	












 specsc                 C   sZ   | du rg S t | tjrg S t | tr| r| dS g S t | tjjr't| S t	d|  )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"  rR   rV   collectionsabcr   r   r   )r|  rB   rB   rC   rl    s   
rl  rn  c                 C   s$   zt j| = W d S  ty   Y d S w rH   )re   rJ  rI  )rn  rB   rB   rC   rL  0  s
   rL  c                   @   s   e Zd Zdd ZdS )Notsetc                 C   s   dS )Nz<NOTSET>rB   rO   rB   rB   rC   __repr__8  s   zNotset.__repr__N)r8   r9   r:   r  rB   rB   rB   rC   r  7  r   r  package_filesc                 c   s    t | } d}| D ]=}d|vo|d}|ddko|d}|r9tj|\}}|dkr8|ds8d}|V  q	|rFtj|}d}|V  q	|spg }| D ]}|d}	d	|	dd	 }
|
rd|
|
 qM|rrt|E d	H  d	S d	S 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setup__editable__TN)r   endswithcountrW   rE   splitextr  dirnamerV   r   r   _iter_rewritable_modules)r  	seen_somefnis_simple_module
is_packagemodule_namer  package_namenew_package_filespartsnew_fnrB   rB   rC   r  ?  s:    

r  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	d
edee ddfddZedefddZedee fddZdeg df ddfddZdvddZdvddZdefddZd
edee dd fddZ	dwdee d eej ddfd!d"Zd#edefd$d%Z e!dxd&d'Z"dyd*d+Z#e$dd,dzd.d/Z%de&e ddfd0d1Z'de&e ddfd2d3Z(dvd4d5Z)dee d6edee fd7d8Z*dee d9ee d:ee d;ed<ed=e+de,ee e
f fd>d?Z-d{dee d@e+ddfdAdBZ.e$ddCde/dD fdEdFZ0dvdGdHZ1dvdIdJZ2dvdKdLZ3dMeddfdNdOZ4dee fdPdQZ5d{dee d@e+ddfdRdSZ6dTe7dUe8ddfdVdWZ9dXedYeddfdZd[Z:dXefd\d]Z;dXed^ed_e<eee f fd`daZ=dXefdbdcZ>dXedded<edeee  fdedfZ?dXedee fdgdhZ@eAdifdXedje+fdkdlZBdwdXefdmdnZCdwdXefdodpZDdqeddfdrdsZEdvdtduZFdS )|r   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                   @   sv   e Zd ZU dZeedf ed< 	 eee	ee
f   ed< 	 eed< 	 dee deee	ee
f   deddf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.
        .rZ   r[   r   rG   Nc                C   s2   t | dt| t | d| t | d| d S )NrZ   r[   r   )object__setattr__tuple)rK   rZ   r[   r   rB   rB   rC   rJ     s   z Config.InvocationParams.__init__)r8   r9   r:   r;   r   rR   __annotations__r   r   r   r{  r   r   rJ   rB   rB   rB   rC   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)	r8   r9   r:   r;   enumautoARGSINCOVATION_DIR	TESTPATHSrB   rB   rB   rC   
ArgsSource  s
    r  Nr   r   r   rG   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$rddl%m&} d | _'d S d S )Nr   )ParserFILE_OR_DIRrB   r   z%(prog)s [options] [z] [z] [...]T)usage
processopt	_ispytest)PathAwareHookProxyra   pytestconfigF)parserr   r  r   )Cache)(
argparsingr  r  r   r   r   argparse	Namespaceoptionr   _processopt_parserr   r,   stash_storecompatr  r   r  r   rn   	_inicache_override_ini	_opt2dest_cleanupr   r  pytest_addoptionr  r   r   r  r  args_sourcerZ   r   _pytest.cacheproviderr  cache)rK   r   r   r  r  _ar  r  rB   rB   rC   rJ     sL   



zConfig.__init__c                 C      | j S )znThe path to the :ref:`rootdir <rootdir>`.

        :type: pathlib.Path

        .. versionadded:: 6.1
        )	_rootpathrO   rB   rB   rC   r/       zConfig.rootpathc                 C   r  )zThe path to the :ref:`configfile <configfiles>`.

        :type: Optional[pathlib.Path]

        .. versionadded:: 6.1
        )_inipathrO   rB   rB   rC   inipath	  r  zConfig.inipathfuncc                 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)r  r   )rK   r  rB   rB   rC   add_cleanup  s   zConfig.add_cleanupc                 C   s^   | j rJ d| _ t  td | jjjt| dd W d    d S 1 s(w   Y  d S )NTdefaultr`   r  )r  r   catch_warningssimplefilterrn   r,  r  r   rO   rB   rB   rC   _do_configure  s   


"zConfig._do_configurec                 C   sH   | j rd| _ | jj| d g | jj_| jr"| j }|  | jsd S d S )NFr`   )r  rn   pytest_unconfigurer,  _call_historyr  pop)rK   finrB   rB   rC   rp     s   

zConfig._ensure_unconfigurec                 C   s   | j d}|d usJ |jS )Nterminalreporter)r   r$  _tw)rK   r  rB   rB   rC   get_terminal_writer(  s
   zConfig.get_terminal_writerrZ   c                 C   s   z|  | W | S  tyB   t| jddsd|v r%ddlm} ||   t| jdds4d|v s4d|v rA| j   t	j
d	  w )
NversionFz	--versionr   )showversionhelpz--helpz-hz8
NOTE: displaying only minimal help due to UsageError.

)parser   r   r  _pytest.helpconfigr  r  
_getparser
print_helpre   rz   r  )rK   r   rZ   r  rB   rB   rC   r   /  s"   	zConfig.pytest_cmdline_parserF   r  c                 C   s   |rt |ddrd}nd}|jdt |dd|d}| jj||d}t|s<t|d	D ]}tj	d
|  tj
  q,d S d S )N	fulltraceFlongnativeT
showlocals)funcargsr  r^   )excreprrF   rb   zINTERNALERROR> %s
)r   rj   rn   pytest_internalerroranyrR   rV   re   rf   r  r{   )rK   rF   r  r^   r  resrg   rB   rB   rC   notify_exceptionH  s   zConfig.notify_exceptionnodeidc                 C   s*   | j j| jkr| j| }t| j j|}|S rH   )r   r   r/  r'   )rK   r  fullpathrB   rB   rC   cwd_relative_nodeidZ  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   r  __dict__updater  r[   r   r   )clsoption_dictrZ   ra   rA  rB   rB   rC   fromdictargsa  s   zConfig.fromdictargsr^  r1   c                 C   sT   |j |j D ]}|j| j|< qt|dr&t| j|js(t| j|j|j d S d S d S )Nr  )_short_opts
_long_optsdestr  rX  r  setattrr  )rK   r^  r   rB   rB   rC   r  k  s   
zConfig._processopt)r  early_configc                 C   s\   |j |jj|jj|d|jj|jdd\}}| jj	||jj|jj
|j|jj|jjd d S )N	testpathsFrZ   r-  r  invocation_dirr/  r  )rZ   r-  r.  r/  r0  r1  )_decide_argsknown_args_namespacefile_or_dirr-  getinir   r   r/  r   r;  r.  r0  r1  )rK   r  rZ   r  rB   rB   rC   pytest_load_initial_conftestss  s    

z$Config.pytest_load_initial_conftestsc                 C   s   | j j|t| jd\}}t|j|j| |jpd | 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pXd| _d S )N	namespace)rootdir_cmd_argra   rootdirinifiler  zExtra command line optionsrZ   
minversionz!Minimally required pytest versionrequired_pluginsz.Plugins that must be present for pytest to run)r   r  rB   )r  parse_known_and_unknown_argscopyr  r   inifilenamer  r  r  r  inicfgrR   r/  
extra_infor  addinioverride_inir  )rK   rZ   nsunknown_argsr/  r  r  rB   rB   rC   _initini  s.   
zConfig._initinic                 C   sl   | j |\}}t|dd}|dkr/ddl}z|j| }W n ty)   d}Y nw | | | | 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.
        
assertmodeplainrewriter   N)	r  r  r   r   r   install_importhookSystemError_mark_plugins_for_rewrite_warn_about_missing_assertion)rK   rZ   r  r  r   r   rn   rB   rB   rC   _consider_importhook  s   
zConfig._consider_importhookc                 C   sF   || j _tjdrdS dd t D }t|D ]}|| qd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<    | ]}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 )ro  N)group)r   eprB   rB   rC   	<genexpr>  s    z=Config._mark_plugins_for_rewrite.<locals>.<genexpr>.<genexpr>N)r  entry_pointsfilesrR   )r   distfilerB   rB   rC   r    s    z3Config._mark_plugins_for_rewrite.<locals>.<genexpr>)	r   r  rW   r   r   r#   distributionsr  rs  )rK   rn   r  r   rB   rB   rC   r
    s   z Config._mark_plugins_for_rewriteviac                 C   s6   || j _z| j j|t| jd W | j `|S | j `w )zValidate known args.r  )r  _config_source_hintr  r  r  )rK   rZ   r  rB   rB   rC   _validate_args  s   zConfig._validate_argsr-  r  r  r/  r  c                C   s   |rt jj}|}||fS ||kr>t jj}|r|}n'g }|D ]}	|ttj|	dd q|r=|s=|r=d}
| jt	|
dd ng }|sKt jj
}t|g}||fS )zDecide the args (initial paths/nodeids) to use given the relevant inputs.

        :param warn: Whether can issue warnings.
        T)	recursivezNo files were found in testpaths; consider removing or adjusting your testpaths configuration. Searching recursively from the current directory instead.r5   
stacklevel)r   r  r  r  extendsortedr@  iglobissue_config_time_warningr-   r  rR   )rK   rZ   r-  r  r  r/  r  sourceresultrE   warning_textrB   rB   rC   r    s0   
zConfig._decide_argsr  c              
   C   s  |rt jdd}t|r| t|d| |d d < | | |r2| | 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 r| jd urt| jj}nt| j}|| j_z| j j!| || j	d W d S  t"y } z| jj#s| jj$r| jt%d|j& dd n W Y d }~d S d }~ww )NPYTEST_ADDOPTSrp  zvia PYTEST_ADDOPTSr  zvia addopts configr  Fr   r  ro  r4   r  )r  rZ   r  z"could not load initial conftests: )'rW   r   r   rZ  r  shlexrV   r  r  r  parse_known_argsr  r  r  _checkversionr  r   r   rt  rj  _validate_plugins_warn_about_skipped_pluginsstrictr  r   r   STRICT_OPTIONr0  r  rR   r   r/  rn   r  rD   r  r  r-   rE   )rK   rZ   r  env_addoptsr0  rr   rB   rB   rC   	_preparse  s`   






zConfig._preparse)r  )NNNc                 c   s    d V  |    d S rH   )_validate_config_optionsrO   rB   rB   rC   pytest_collection=  s   zConfig.pytest_collectionc                 C   sr   dd l }| jdd }|r5ddlm} t|ts |d| j ||||j	kr7|d| j||j	f d S d S )Nr   r  Versionz'%s: 'minversion' must be a single valuez6%s: 'minversion' requires pytest-%s, actual pytest-%s')
r2   r  r   packaging.versionr0  r   rR   r   r  __version__)rK   r2   minverr0  rB   rB   rC   r&  D  s&   
	zConfig._checkversionc                 C   s(   t |  D ]}| d| d qd S )NzUnknown config option: rb   )r  _get_unknown_ini_keys_warn_or_fail_if_strict)rK   keyrB   rB   rC   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 ]4}z||}	W n |y?   |	| Y q)w |	j
|vrK|	| q)|	jj|||	j
 dds]|	| q)|rjtd	d
|d S )Nr  r   r/  )InvalidRequirementRequirementc                 S   s   i | ]	\}}|j |jqS rB   )project_namer  )r   r  r  rB   rB   rC   
<dictcomp>i  s    z,Config._validate_plugins.<locals>.<dictcomp>T)prereleaseszMissing required plugins: {}r   )r  r  r1  r0  packaging.requirementsr7  r8  r   list_plugin_distinfor   r   	specifiercontainsr   rN   r   )
rK   r  r0  r7  r8  plugin_infoplugin_dist_infomissing_pluginsrequired_pluginreqrB   rB   rC   r'  _  s6   



zConfig._validate_pluginsr   c                 C   s&   | j jrt|| jt|dd d S )Nr5   r  )r  strict_configr   r  r-   )rK   r   rB   rB   rC   r5    s   zConfig._warn_or_fail_if_strictc                    s   | j j  fdd| jD S )Nc                    s   g | ]}| vr|qS rB   rB   )r   r   parser_inicfgrB   rC   
<listcomp>  s    z0Config._get_unknown_ini_keys.<locals>.<listcomp>)r  _inidictr  rO   rB   rF  rC   r4    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_	z%| jj
|| j| jd}| j|| jj| d| jj| jdd	\| _ | _W d S  tyW   Y d S w )
Nz:can only parse cmdline args at most once per Config object)r   r  r  )ra   rZ   Tr  r  r  )rZ   rn   pytest_addhooksr  r   r   r,  pytest_cmdline_preparser  after_preparseparse_setoptionr  r  r  r-  r  r   r   r/  r  r   )rK   rZ   r  rB   rB   rC   r    s0   

zConfig.parsewarningr  c                 C   s   | j drdS | jjpg }| d}tjdd}tdt| t	|| tj
||d W d   n1 s8w   Y  |rbt|d }|jj|j|jjf}| jjjt|d	 d
d|dd dS 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   ra   rp  )warning_messagewhenr  locationr  )r   rq  r  pythonwarningsr  r   r  r  r   apply_warning_filtersr  re   	_getframef_codeco_filenamef_linenoco_namern   pytest_warning_recordedr  r   )rK   rN  r  cmdline_filtersconfig_filtersrecordsframerT  rB   rB   rC   r    s*   


z Config.issue_config_time_warningr   rg   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   )rK   r   rg   rA  rB   rB   rC   r+    s   
zConfig.addinivalue_linec                 C   s8   z| j | W S  ty   | | | j |< }| Y S w )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.
        )r  rI  _getini)rK   r   valrB   rB   rC   r    s   zConfig.getinir   valuec                 C   s   d| }t ||)Nzunknown configuration type: )rq   )rK   r   r   rc  rx   rB   rB   rC   _getini_unknown_type  s   

zConfig._getini_unknown_typec           	   
      st  z| j j| \}}}W n ty } ztd||d }~ww | |}|d u rKz| j| }W n tyJ   |d ur?| Y S |d u rFY dS g  Y S w |}|dkrq| jd usXJ | jj t|t	rft
|n|} fdd|D S |dkrt|t	rt
|S |S |dkrt|t	rdd td	d
 |dD S |S |dkrtt	| S |dkr|S |d u r|S | |||S )Nzunknown configuration value: rp  pathsc                    s   g | ]} | qS rB   rB   )r   rA  dprB   rC   rH        z"Config._getini.<locals>.<listcomp>rZ   linelistc                 S   s   g | ]}|r|qS rB   rB   )r   trB   rB   rC   rH    rh  c                 S   s   |   S rH   r\  )rA  rB   rB   rC   <lambda>  s    z Config._getini.<locals>.<lambda>rb   r&  string)r  rI  rI  rq   _get_override_ini_valuer  r  r   r   rR   r$  rV   map
_strtoboolr\  rd  )	rK   r   descriptionr   r  rr   override_valuerc  input_valuesrB   rf  rC   ra    sH   

zConfig._getinirE   c           	      C   s   z| j ||| d|\}}W n
 ty   Y d S w |jd us"J t|jj}g }|D ]}t|tj	r9t|}n|
dtj}t|| }|| q,|S )Nr1  r  )r   rK  	getoptionrI  rg  r   r   r   rW   r   r  rX   r&   r   )	rK   r   rE   r/  rH  relrootsmodpathvaluesrelrootrB   rB   rC   _getconftest_pathlist  s"   
zConfig._getconftest_pathlistc                 C   s^   d }| j D ]'}z
|dd\}}W n ty% } ztd||d }~ww ||kr,|}q|S )Nr   r   z9-o/--override-ini expects option=value style (got: {!r}).)r  rV   rq   r   rN   )rK   r   rc  
ini_configr6  user_ini_valuerr   rB   rB   rC   rn  -  s$   
zConfig._get_override_ini_valueFskipc              
   C   s   | j ||}zt| j|}|du r|rt||W S  tyI } z#|tur.|W  Y d}~S |r=ddl}|d|d td||d}~ww )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 )	r  r   r   r  r   notsetr2   r|  rq   )rK   r   r  r|  rb  rr   r2   rB   rB   rC   rt  @  s   	zConfig.getoptionc                 C   s
   |  |S )z$Deprecated, use getoption() instead.rt  rK   r   rE   rB   rB   rC   getvalueX  s   
zConfig.getvaluec                 C   s   | j |ddS )z-Deprecated, use getoption(skip=True) instead.T)r|  r~  r  rB   rB   rC   getvalueorskip\  r(  zConfig.getvalueorskipr   c                 C   s2   t  s|dkr
d}nd}| jt|dd d S 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?)
r5   r  )_assertion_supportedr  r-   )rK   r   r"  rB   rB   rC   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 : r4   r  )r   r   r  r-   )rK   r  rx   rB   rB   rC   r(  u  s   z"Config._warn_about_skipped_pluginsrz  rH   )rG   r   )r^  r1   rG   N)r  r   rG   N)T)Gr8   r9   r:   r;   r"   dataclasses	dataclassr   r  Enumr  r   r   rJ   propertyr   r/  r  r   r  r  rp   r!   r  r   rR   r   r   r   r  r  r  r  classmethodr  r  hookimplr  r   r  r  r
  r  r&  r   r  r,  r   r.  r&  r-  r'  r5  r4  r  Warningintr  r+  r  r   rd  ra  ry  rn  r}  rt  r  r  r  r(  rB   rB   rB   rC   r     s    

!
C		

	


	
	
+;


 #"6

c                   C   s   zJ  t y   Y dS w )NFT)AssertionErrorrB   rB   rB   rC   r  }  s
   r  ra   r  c                 C   s\   t |d}| jjdkrd|_n	| jjdkrd|_| jjdkr#d|_|S | jjdkr,d|_|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!   r  color	hasmarkupcode_highlight)ra   r  rt   rB   rB   rC   create_terminal_writer  s   
	r  rb  c                 C   s.   |   } | dv r
dS | dv rdS td| )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  rj  trueon1T)r]  r  ffalseoff0Fzinvalid truth value )lowerrq   )rb  rB   rB   rC   rp    s   	rp  2   )maxsizer`  escapezwarnings._ActionKindc             
   C   s  d}t d|  d}| d}t|dkr,d}t dt| d| d	}t|j|d
t|dk r=|d t|dk s2dd |D \}}}	}
}zt|}W n tjyg } z
t|jt	|d
d}~ww zt
|	}W n ty   t }|jdd}t|j|d
w |r|rt|}|
r|rt|
d }
|rzt|}|dk rtdW n ty } zt|jd|d| d
d}~ww 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}
        :r7   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
            )errorrp  c                 s   s    | ]}|  V  qd S rH   rk  )r   srB   rB   rC   r    s    z'parse_warning_filter.<locals>.<genexpr>Nr  )r^   z\Zr   znumber is negativezinvalid lineno r  )r   rV   rZ  r   rN   r   r   
_getaction_OptionErrorrR   _resolve_warning_categoryrQ   r   from_currentrj   rer  r  rq   )r`  r  __tracebackhide__error_templater  doc_urlr  action_r   	category_modulelineno_actionrr   categoryrs   exception_textlinenorB   rB   rC   parse_warning_filter  sj   
	

r  r  c                 C   sr   d}| st S d| vrddl}| }n| d\}}}t|dd|g}t||}t|t s2t| 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
rpartitionru  r   
issubclassr   r	   r   )r  r  r   klassr  r  catrB   rB   rC   r    s   

r  r^  r]  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   rO  r  )r^  r]  r`  rB   rB   rC   rV    s
   rV  )NN)rG   r   rH   )r;   r  collections.abcr~  r  r  r  r@  r   rW   r  r$  re   r!  r   	functoolsr   pathlibr   textwrapr   r   r   typingr   r   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   pluggyr   r   r   _pytest._coder   _pytest.deprecated_pytest.hookspec
exceptionsr   r   	findpathsr   r   r    _pytest._ior!   _pytest.compatr"   r#   _pytest.outcomesr$   r%   _pytest.pathlibr&   r'   r(   r)   r*   r+   _pytest.stashr,   _pytest.warning_typesr-   r.   _pytest._code.coder/   _pytest.terminalr0   r  r1   r  r{  r  r   IntEnumr3   rQ   rD   _codeTracebackEntryr&  rY   rR   r  ry   r   r   r   r   rc  version_infor   r   rr  rP  r   r   rc   r   r   r   r"  rl  rL  r  r}  r  r   r  r  rp  r  r  r  rV  rB   rB   rB   rC   <module>   s   	


2





 


     
A      

G