o
    hFh                     @   s  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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/m0Z0 d d$l1m2Z2 erd d%l3m4Z4 d d&lm5Z5 d'Z6eej7j8Z9d(e:d)ee: fd*d+Z;d,ed-ed)dfd.d/Z<d0ed1 d,ee d-ee d)efd2d3Z=ed4d1d5Z>G d6d7 d7e?Z@G d8d1 d1e@d9ZAd:d1d)eee:ef eeB f fd;d<ZCG d=d> d>eAZDd?d@d,ed)ee: fdAdBZEG dCdD dDeDZFG dEdF dFeFZGG dGdH dHeAZHdS )I    N)	signature)Path)Any)Callable)cast)Iterable)Iterator)List)MutableMapping)Optional)overload)Set)Tuple)Type)TYPE_CHECKING)TypeVar)Union)getfslineno)ExceptionInfo)TerminalRepr)	Traceback)cached_property)LEGACY_PATH)Config)ConftestImportFailure)#FSCOLLECTOR_GETHOOKPROXY_ISINITPATH)NODE_CTOR_FSPATH_ARG)Mark)MarkDecorator)NodeKeywords)fail)absolutepath)
commonpath)Stash)PytestWarning)Session)_TracebackStyle/nodeidreturnc                 c   s    d}|  d}|dkrd}dV  	 |  t||}|dkrn|dkr)| d| V  |tt }q	 |  d|}|dkr<n|dkrG| d| V  |td }q1| rU| V  dS dS )a  Return the parent node IDs of a given node ID, inclusive.

    For the node ID

        "testing/code/test_excinfo.py::TestFormattedExcinfo::test_repr_source"

    the result would be

        ""
        "testing"
        "testing/code"
        "testing/code/test_excinfo.py"
        "testing/code/test_excinfo.py::TestFormattedExcinfo"
        "testing/code/test_excinfo.py::TestFormattedExcinfo::test_repr_source"

    Note that / components are only considered until the first ::.
    r   ::N )findSEPlen)r(   posfirst_colonsat r3   C/var/www/html/ai/venv/lib/python3.10/site-packages/_pytest/nodes.pyiterparentnodeids4   s2   

r5   pathfspathc                 C   s&   t || krtd|d| dd S )NzPath(z) != z8
if both path and fspath are given they need to be equal)r   
ValueError)r6   r7   r3   r3   r4   _check_patha   s
   r9   	node_typeNodec                 C   sR   |d urt jtj| jddd |d ur|d urt|| |S |d us%J t|S )N)node_type_name   
stacklevel)warningswarnr   format__name__r9   r   )r:   r6   r7   r3   r3   r4   _imply_pathi   s   
rD   	_NodeType)boundc                       s$   e Zd Zdd Z fddZ  ZS )NodeMetac                 O   s*   dj | j d| j d}t|dd d S )NzDirect construction of {name} has been deprecated, please use {name}.from_parent.
See https://docs.pytest.org/en/stable/deprecations.html#node-construction-changed-to-node-from-parent for more details..nameF)pytrace)rB   
__module__rC   r    )selfkkwmsgr3   r3   r4   __call__   s   zNodeMeta.__call__c              
      s   z
t  j|i |W S  tyC   tt| d  fdd| D }ddlm} t	||  dt
| d t  j|i | Y S w )N__init__c                    s    i | ]\}}| j v r||qS r3   )
parameters).0rN   vsigr3   r4   
<dictcomp>   s     z$NodeMeta._create.<locals>.<dictcomp>   )PytestDeprecationWarningz7 is not using a cooperative constructor and only takes z.
See https://docs.pytest.org/en/stable/deprecations.html#constructors-of-custom-pytest-node-subclasses-should-take-kwargs for more details.)superrQ   	TypeErrorr   getattritemswarning_typesrZ   r@   rA   set)rM   rN   rO   known_kwrZ   	__class__rV   r4   _create   s   	zNodeMeta._create)rC   rL   __qualname__rQ   rd   __classcell__r3   r3   rb   r4   rG      s    	rG   c                   @   sR  e Zd ZU dZeed< dZ						dDdedddee	 d	d
dee dee
 dee ddfddZedEddZedd ZdefddZdeddfddZedefddZdefddZdFddZdFdd Zded  fd!d"Z	#dGd$eeef d%eddfd&d'ZdHdee dee fd(d)Z 	dHdee dee!d ef  fd*d+Z"e#dedee fd,d-Z$e#ded.edefd/d-Z$	dHded.ee dee fd0d-Z$de%e fd1d2Z&dee fd3d4Z'd5e(g e)f ddfd6d7Z*d8e+e, dee, fd9d:Z-d;e.e/ de0fd<d=Z1	dHd;e.e/ d>d?de2fd@dAZ3	dHd;e.e/ d>d?deee2f fdBdCZ4dS )Ir;   zBase class of :class:`Collector` and :class:`Item`, the components of
    the test collection tree.

    ``Collector``\'s are the internal nodes of the tree, and ``Item``\'s are the
    leaf nodes.
    r7   )rJ   parentconfigsessionr6   _nodeid_store__dict__NrJ   rg   zOptional[Node]rh   ri   zOptional[Session]r6   r(   r)   c                 C   s   || _ || _|r|| _n
|std|j| _|r|| _n
|s"td|j| _|d u r4|d u r4t|dd }tt| ||d| _t	| | _
g | _t | _|d urXd|vsTJ || _n| js_td| jjd | j  | _t | _| j| _d S )Nz!config or parent must be providedz"session or parent must be providedr6   r7   z::()z!nodeid or parent must be providedr*   )rJ   rg   rh   r\   ri   r]   rD   typer6   r   keywordsown_markersr`   extra_keyword_matchesrj   r(   r#   stashrk   )rM   rJ   rg   rh   ri   r7   r6   r(   r3   r3   r4   rR      s4   
zNode.__init__c                 K   s4   d|v rt dd|v rt d| jdd|i|S )a:  Public constructor for Nodes.

        This indirection got introduced in order to enable removing
        the fragile logic from the node constructors.

        Subclasses can use ``super().from_parent(...)`` when overriding the
        construction.

        :param parent: The parent node of this Node.
        rh   z.config is not a valid argument for from_parentri   z/session is not a valid argument for from_parentrg   Nr3   )r\   rd   )clsrg   rO   r3   r3   r4   from_parent   s
   zNode.from_parentc                 C   s   | j | jS )z6fspath-sensitive hook proxy used to call pytest hooks.)ri   gethookproxyr6   rM   r3   r3   r4   ihook
  s   z
Node.ihookc                 C   s   d | jjt| dd S )Nz<{} {}>rJ   )rB   rc   rC   r]   rv   r3   r3   r4   __repr__  s   zNode.__repr__warningc                 C   sN   t |tstd|t| \}}|dusJ tj|dt||d d dS )aw  Issue a warning for this Node.

        Warnings will be displayed after the test session, unless explicitly suppressed.

        :param Warning warning:
            The warning instance to issue.

        :raises ValueError: If ``warning`` instance is not a subclass of Warning.

        Example usage:

        .. code-block:: python

            node.warn(PytestWarning("some message"))
            node.warn(UserWarning("some message"))

        .. versionchanged:: 6.2
            Any subclass of :class:`Warning` is now accepted, rather than only
            :class:`PytestWarning <pytest.PytestWarning>` subclasses.
        z<warning must be an instance of Warning or subclass, got {!r}NrY   )categoryfilenamelineno)
isinstanceWarningr8   rB   get_fslocation_from_itemr@   warn_explicitstr)rM   ry   r6   r|   r3   r3   r4   rA     s   

z	Node.warnc                 C   s   | j S )z;A ::-separated string denoting its collection tree address.)rj   rv   r3   r3   r4   r(   9  s   zNode.nodeidc                 C   s
   t | jS N)hashrj   rv   r3   r3   r4   __hash__>  s   
zNode.__hash__c                 C      d S r   r3   rv   r3   r3   r4   setupA     z
Node.setupc                 C   r   r   r3   rv   r3   r3   r4   teardownD  r   zNode.teardownc                 C   s4   g }| }|dur| | |j}|dus|  |S )zReturn list of all parent collectors up to self, starting from
        the root of collection tree.

        :returns: The nodes.
        N)appendrg   reverse)rM   chainitemr3   r3   r4   	listchainG  s   
zNode.listchainTmarkerr   c                 C   sp   ddl m} t|tr|}nt|trt||}ntd|| j|j< |r.| j	
|j dS | j	d|j dS )zDynamically add a marker object to the node.

        :param marker:
            The marker.
        :param append:
            Whether to append the marker, or prepend it.
        r   )MARK_GENz'is not a string or pytest.mark.* MarkerN)_pytest.markr   r}   r   r   r]   r8   ro   rJ   rp   r   markinsert)rM   r   r   r   marker_r3   r3   r4   
add_markerU  s   


zNode.add_markerc                 C   s   dd | j |dD S )zIterate over all markers of the node.

        :param name: If given, filter the results by the name attribute.
        :returns: An iterator of the markers of the node.
        c                 s   s    | ]}|d  V  qdS )rY   Nr3   rT   xr3   r3   r4   	<genexpr>s  s    z$Node.iter_markers.<locals>.<genexpr>rI   )iter_markers_with_noderM   rJ   r3   r3   r4   iter_markersm  s   zNode.iter_markersc                 c   sF    t |  D ]}|jD ]}|du st|dd|kr||fV  qqdS )zIterate over all markers of the node.

        :param name: If given, filter the results by the name attribute.
        :returns: An iterator of (node, mark) tuples.
        NrJ   )reversedr   rp   r]   )rM   rJ   noder   r3   r3   r4   r   u  s   

zNode.iter_markers_with_nodec                 C   r   r   r3   r   r3   r3   r4   get_closest_marker     zNode.get_closest_markerdefaultc                 C   r   r   r3   rM   rJ   r   r3   r3   r4   r     r   c                 C   s   t | j|d|S )zReturn the first marker matching the name, from closest (for
        example function) to farther level (for example module level).

        :param default: Fallback return value if no marker was found.
        :param name: Name to filter by.
        rI   )nextr   r   r3   r3   r4   r     s   	c                 C   s$   t  }|  D ]}||j q|S )z;Return a set of all extra keywords in self and any parents.)r`   r   updaterq   )rM   extra_keywordsr   r3   r3   r4   listextrakeywords  s   zNode.listextrakeywordsc                 C   s   dd |   D S )Nc                 S   s   g | ]}|j qS r3   rI   r   r3   r3   r4   
<listcomp>  s    z"Node.listnames.<locals>.<listcomp>)r   rv   r3   r3   r4   	listnames  s   zNode.listnamesfinc                 C   s   | j j||  dS )zRegister a function to be called without arguments when this node is
        finalized.

        This method can only be called when this node is active
        in a setup chain, for example during self.setup().
        N)ri   _setupstateaddfinalizer)rM   r   r3   r3   r4   r     s   zNode.addfinalizerrs   c                 C   s@   | }|rt ||s|j}|rt ||r	|du st ||sJ |S )zGet the next parent node (including self) which is an instance of
        the given class.

        :param cls: The node class to search for.
        :returns: The node, if found.
        N)r}   rg   )rM   rs   currentr3   r3   r4   	getparent  s   zNode.getparentexcinfoc                 C   s   |j S r   )	traceback)rM   r   r3   r3   r4   _traceback_filter  s   zNode._traceback_filterstylezOptional[_TracebackStyle]c                 C   s  ddl m} t|jtrt|jj}t|jtj	r |jj
s d}t|j|r+|j S | jddr7d}d}n	| j}|dkr@d}|d u rR| jddd	krPd	}nd}| jd
ddkr^d}nd}ztt | jjjk}W n tyx   d}Y nw |jd|| jdd|||dS )Nr   )FixtureLookupErrorvalue	fulltraceFlongautotbstyleshortverboserY   T
showlocals)funcargsabspathr   r   tbfiltertruncate_locals)_pytest.fixturesr   r}   r   r   r   from_exc_infor   r    	ExceptionrK   
formatreprrh   	getoptionr   r   osgetcwdinvocation_paramsdirOSErrorgetrepr)rM   r   r   r   r   r   r   r3   r3   r4   _repr_failure_py  sD   
zNode._repr_failure_pyc                 C   s   |  ||S )zReturn a representation of a collection or test failure.

        .. seealso:: :ref:`non-python tests`

        :param excinfo: Exception information for the failure.
        )r   )rM   r   r   r3   r3   r4   repr_failure     zNode.repr_failure)NNNNNN)rg   r;   r)   N)Tr   )5rC   rL   re   __doc__r   __annotations__	__slots__r   r   r   r   rR   classmethodrt   propertyrw   rx   r~   rA   r(   intr   r   r   r	   r   r   r   boolr   r   r   r   r   r   r   r   r   r   r   r   objectr   r   rE   r   r   BaseExceptionr   r   r   r   r   r3   r3   r3   r4   r;      s   
 	
=
'



	

	
:
)	metaclassr   c                 C   sL   t | dd}|dur|dd S t | dd}|durt|S t | dddfS )a  Try to extract the actual location from a node, depending on available attributes:

    * "location": a pair (path, lineno)
    * "obj": a Python object that the node wraps.
    * "fspath": just a path

    :rtype: A tuple of (str|Path, int) with filename and 0-based line number.
    locationN   objr7   zunknown locationr+   )r]   r   )r   r   r   r3   r3   r4   r     s   
r   c                   @   sj   e Zd ZdZG dd deZdeed  fddZde	e
 deeef fd	d
Zde	e
 defddZdS )	CollectorzBase class of all collectors.

    Collector create children through `collect()` and thus iteratively build
    the collection tree.
    c                   @      e Zd ZdZdS )zCollector.CollectErrorz6An error during collection, contains a custom message.NrC   rL   re   r   r3   r3   r3   r4   CollectError      r   r)   )Itemr   c                 C      t d)z;Collect children (items and collectors) for this collector.abstractNotImplementedErrorrv   r3   r3   r4   collect  s   zCollector.collectr   c                 C   sX   t |j| jr| jdds|j}t|jd S | jdd}|dkr%d}| j||dS )zyReturn a representation of a collection failure.

        :param excinfo: Exception information for the failure.
        r   Fr   r   r   r   )r   )r}   r   r   rh   r   r   argsr   )rM   r   excr   r3   r3   r4   r     s   zCollector.repr_failurec                 C   sD   t | dr|j}|j| jd}||kr|jtd}|j|S |jS )Nr6   r6   )excludepath)hasattrr   cutr6   tracebackcutdirfilter)rM   r   r   
ntracebackr3   r3   r4   r   4  s   
zCollector._traceback_filterN)rC   rL   re   r   r   r   r   r   r   r   r   r   r   r   r   r   r3   r3   r3   r4   r     s    

r   ri   r%   c                 C   sD   | j D ]}t|||krt||}|dkrd  S |  S qd S )NrH   r,   )_initialpathsr"   r   relative_to)ri   r6   initial_pathrelr3   r3   r4   _check_initialpaths_for_relpath>  s   
r   c                       s   e Zd ZdZ								ddee deeeef  dee dee	 dee dee
 d	ed
 dee	 ddf fddZeddddee dee f fddZdddZdee	df defddZ  ZS )FSCollectorz%Base class for filesystem collectors.Nr7   path_or_parentr6   rJ   rg   rh   ri   r%   r(   r)   c	           
         sB  |r t |tr|d u sJ tt|}nt |tr |d u sJ |}tt| ||d}|d u rV|j}|d urV|j|krVz|	|j}	W n	 t
yJ   Y nw t|	}|tjt}|| _|d u rf|d uscJ |j}|d u rzt| j	|jj}W n t
y   t||}Y nw |rtjtkr|tjt}t j||||||d d S )Nrm   )rJ   rg   rh   ri   r(   r6   )r}   r;   r   r   r   rD   rn   rJ   r6   r   r8   r   replacer   sepr.   ri   rh   rootpathr   r[   rR   )
rM   r7   r   r6   rJ   rg   rh   ri   r(   r   rb   r3   r4   rR   I  sL   


zFSCollector.__init__)r7   r6   c                   s   t  jd|||d|S )zThe public constructor.)rg   r7   r6   Nr3   )r[   rt   )rs   rg   r7   r6   rO   rb   r3   r4   rt     s   
zFSCollector.from_parentos.PathLike[str]c                 C      t jtdd | j|S Nr   r>   )r@   rA   r   ri   ru   )rM   r7   r3   r3   r4   ru        zFSCollector.gethookproxyc                 C   r   r   )r@   rA   r   ri   
isinitpath)rM   r6   r3   r3   r4   r     r   zFSCollector.isinitpath)NNNNNNNN)r7   r   )rC   rL   re   r   r   r   r   r   r;   r   r   rR   r   rt   ru   r   r   rf   r3   r3   rb   r4   r   F  sN    	
6
"r   c                   @   r   )FilezOBase class for collecting tests from a file.

    :ref:`non-python tests`.
    Nr   r3   r3   r3   r4   r     r   r   c                	       s   e Zd ZdZdZ				ddee ded dee ddf fdd	Zdd
dZ	dddZ
dedededdfddZdeedef ee ef fddZedeeee ef fddZ  ZS )r   zBase class of all test invocation items.

    Note that for a single function there might be multiple test invocation items.
    Nrh   ri   r%   r(   r)   c                    s6   t  j||f|||d| g | _g | _|   d S )N)rh   ri   r(   )r[   rR   _report_sectionsuser_properties-_check_item_and_collector_diamond_inheritance)rM   rJ   rg   rh   ri   r(   rO   rb   r3   r4   rR     s   zItem.__init__c                 C   sd   t | }d}t||drdS t||d ddd |jD }|r0t|j d| d	t dS dS )
z
        Check if the current type inherits from both File and Collector
        at the same time, emitting a warning accordingly (#8447).
        )_pytest_diamond_inheritance_warning_shownFNTz, c                 s   s     | ]}t |tr|jV  qd S r   )
issubclassr   rC   )rT   baser3   r3   r4   r     s    

zEItem._check_item_and_collector_diamond_inheritance.<locals>.<genexpr>zF is an Item subclass and should not be a collector, however its bases z are collectors.
Please split the Collectors and the Item into separate node types.
Pytest Doc example: https://docs.pytest.org/en/latest/example/nonpython.html
example pull request on a plugin: https://github.com/asmeurer/pytest-flakes/pull/40/)	rn   r]   setattrjoin	__bases__r@   rA   rC   r$   )rM   rs   	attr_nameproblemsr3   r3   r4   r     s    
z2Item._check_item_and_collector_diamond_inheritancec                 C   r   )zRun the test case for this item.

        Must be implemented by subclasses.

        .. seealso:: :ref:`non-python tests`
        z,runtest must be implemented by Item subclassr   rv   r3   r3   r4   runtest  s   zItem.runtestwhenkeycontentc                 C   s   |r| j |||f dS dS )a  Add a new report section, similar to what's done internally to add
        stdout and stderr captured output::

            item.add_report_section("call", "stdout", "report section contents")

        :param str when:
            One of the possible capture states, ``"setup"``, ``"call"``, ``"teardown"``.
        :param str key:
            Name of the section, can be customized at will. Pytest uses ``"stdout"`` and
            ``"stderr"`` internally.
        :param str content:
            The full contents as a string.
        N)r   r   )rM   r	  r
  r  r3   r3   r4   add_report_section  s   zItem.add_report_sectionr   c                 C   s   | j ddfS )aP  Get location information for this item for test reports.

        Returns a tuple with three elements:

        - The path of the test (default ``self.path``)
        - The 0-based line number of the test (default ``None``)
        - A name of the test to be shown (default ``""``)

        .. seealso:: :ref:`non-python tests`
        Nr,   r   rv   r3   r3   r4   
reportinfo  r   zItem.reportinfoc                 C   sL   |   }tt|d }| j|}t|d tu sJ ||d |d fS )z
        Returns a tuple of ``(relfspath, lineno, testname)`` for this item
        where ``relfspath`` is file path relative to ``config.rootpath``
        and lineno is a 0-based line number.
        r   r   rY   )r  r!   r   r7   ri   _node_location_to_relpathrn   r   )rM   r   r6   	relfspathr3   r3   r4   r     s
   zItem.location)NNNNr   )rC   rL   re   r   nextitemr   r   r   rR   r   r  r  r   r   r   r  r   r   rf   r3   r3   rb   r4   r     s,    

	$&r   )Ir   r@   inspectr   pathlibr   typingr   r   r   r   r   r	   r
   r   r   r   r   r   r   r   r   _pytest._code_pytestr   _pytest._code.coder   r   r   _pytest.compatr   r   _pytest.configr   r   _pytest.deprecatedr   r   _pytest.mark.structuresr   r   r   _pytest.outcomesr    _pytest.pathlibr!   r"   _pytest.stashr#   _pytest.warning_typesr$   _pytest.mainr%   r&   r.   __file__rg   r   r   r5   r9   rD   rE   rn   rG   r;   r   r   r   r   r   r   r   r3   r3   r3   r4   <module>   s    -
  &`.N