B
    ܇\Q5                 @   s   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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Zeje	j Zd	d
 Zdd ZG dd deZdd ZG dd deZdd ZG dd deZG dd deZG dd deZdS )    )absolute_import)division)print_functionN)getfslineno)NodeKeywords)fail/c             C   s0   | dkrg S |  t}|d  d|dd< |S )a  Split a nodeid into constituent 'parts'.

    Node IDs are strings, and can be things like:
        ''
        'testing/code'
        'testing/code/test_excinfo.py'
        'testing/code/test_excinfo.py::TestFormattedExcinfo'

    Return values are lists e.g.
        []
        ['testing', 'code']
        ['testing', 'code', 'test_excinfo.py']
        ['testing', 'code', 'test_excinfo.py', 'TestFormattedExcinfo', '()']
     z::N)splitSEP)nodeidparts r   ,lib/python3.7/site-packages/_pytest/nodes.py
_splitnode   s
    
r   c             C   s8   t | }t |}t|t|k r$dS |dt| |kS )zReturn True if the nodeid is a child node of the baseid.

    E.g. 'foo/bar::Baz' is a child of 'foo', 'foo/bar' and 'foo/bar::Baz', but not of 'foo/blorp'
    FN)r   len)Zbaseidr   Z
base_partsZ
node_partsr   r   r   ischildnode-   s
    r   c               @   s   e Zd ZdZd*ddZedd Zdd Zd	d
 Zedd Z	dd Z
dd Zdd Zdd Zd+ddZd,ddZd-ddZd.ddZdd Zd d! Zd"d# Zd$d% Zd&d' Zd/d(d)ZeZdS )0Nodez~ base class for Collector and Item the test collection tree.
    Collector subclasses have children, Items are terminal nodes.Nc             C   s   || _ || _|p|j| _|p |j| _|p2t|dd | _t| | _g | _t	 | _
i | _|d k	rpd|ksht|| _n(| jj| _| j dkr|  jd| j  7  _d S )Nfspathz::()z()z::)nameparentconfigsessiongetattrr   r   keywordsown_markerssetextra_keyword_matchesZ_name2pseudofixturedefAssertionError_nodeidr   )selfr   r   r   r   r   r   r   r   r   __init__=   s    


zNode.__init__c             C   s   | j | jS )z6 fspath sensitive hook proxy used to call pytest hooks)r   Zgethookproxyr   )r!   r   r   r   ihookc   s    z
Node.ihookc             C   s   d| j jt| dd f S )Nz<%s %s>r   )	__class____name__r   )r!   r   r   r   __repr__h   s    zNode.__repr__c             C   sZ   ddl m} t||s$td|t| \}}tj|dt||dk	rN|d ndd dS )a  Issue a warning for this item.

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

        :param Warning warning: the warning instance to issue. Must be a subclass of PytestWarning.

        :raise ValueError: if ``warning`` instance is not a subclass of PytestWarning.

        Example usage:

        .. code-block:: python

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

        r   )PytestWarningzBwarning must be an instance of PytestWarning or subclass, got {!r}N   )categoryfilenamelineno)	Z_pytest.warning_typesr'   
isinstance
ValueErrorformatget_fslocation_from_itemwarningswarn_explicitstr)r!   Zwarningr'   pathr+   r   r   r   warnk   s    
z	Node.warnc             C   s   | j S )z= a ::-separated string denoting its collection tree address. )r    )r!   r   r   r   r      s    zNode.nodeidc             C   s
   t | jS )N)hashr   )r!   r   r   r   __hash__   s    zNode.__hash__c             C   s   d S )Nr   )r!   r   r   r   setup   s    z
Node.setupc             C   s   d S )Nr   )r!   r   r   r   teardown   s    zNode.teardownc             C   s2   g }| }x|dk	r$| | |j}q
W |  |S )ze return list of all parent collectors up to self,
            starting from root of collection tree. N)appendr   reverse)r!   chainitemr   r   r   	listchain   s    


zNode.listchainTc             C   sn   ddl m}m} t|tjr(t||}nt||s:td|| j|j	< |rZ| j
|j n| j
d|j dS )zdynamically add a marker object to the node.

        :type marker: ``str`` or ``pytest.mark.*``  object
        :param marker:
            ``append=True`` whether to append the marker,
            if ``False`` insert at position ``0``.
        r   )MarkDecoratorMARK_GENz'is not a string or pytest.mark.* MarkerN)Z_pytest.markr>   r?   r,   sixZstring_typesr   r-   r   r   r   r9   markinsert)r!   Zmarkerr9   r>   r?   r   r   r   
add_marker   s    
zNode.add_markerc             C   s   dd | j |dD S )z
        :param name: if given, filter the results by the name attribute

        iterate over all markers of the node
        c             s   s   | ]}|d  V  qdS )r(   Nr   ).0xr   r   r   	<genexpr>   s    z$Node.iter_markers.<locals>.<genexpr>)r   )iter_markers_with_node)r!   r   r   r   r   iter_markers   s    zNode.iter_markersc             c   sL   xFt |  D ]6}x0|jD ]&}|dks6t|dd|kr||fV  qW qW dS )z
        :param name: if given, filter the results by the name attribute

        iterate over all markers of the node
        returns sequence of tuples (node, mark)
        Nr   )reversedr=   r   r   )r!   r   ZnoderA   r   r   r   rG      s    zNode.iter_markers_with_nodec             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 of no marker was found
        :param name: name to filter by
        )r   )nextrH   )r!   r   defaultr   r   r   get_closest_marker   s    zNode.get_closest_markerc             C   s(   t  }x|  D ]}||j qW |S )z< Return a set of all extra keywords in self and any parents.)r   r=   updater   )r!   Zextra_keywordsr<   r   r   r   listextrakeywords   s    zNode.listextrakeywordsc             C   s   dd |   D S )Nc             S   s   g | ]
}|j qS r   )r   )rD   rE   r   r   r   
<listcomp>   s    z"Node.listnames.<locals>.<listcomp>)r=   )r!   r   r   r   	listnames   s    zNode.listnamesc             C   s   | j j||  dS )z register a function to be called 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)r   Z_setupstateaddfinalizer)r!   Zfinr   r   r   rQ      s    zNode.addfinalizerc             C   s"   | }x|rt ||s|j}qW |S )z] get the next parent node (including ourself)
        which is an instance of the given class)r,   r   )r!   clsZcurrentr   r   r   	getparent   s    
zNode.getparentc             C   s   d S )Nr   )r!   excinfor   r   r   _prunetraceback   s    zNode._prunetracebackc             C   s  | tjr |jjs t|jS | jj}| |j	r>|j
 S d}| jjjrRd}nBtj|jd g}| | t|jdkr||_d}|dkrd}|d kr| jjjdkrd}nd}| jjjdkrd}nd}yt  d}W n tk
r   d}Y nX |jd|| jjj|||d	S )
NTZlongr
   r   Fautoshortr(   )Zfuncargsabspath
showlocalsstyletbfiltertruncate_locals)errisinstancer   	ExceptionvalueZpytracer@   Z	text_typer   Z_fixturemanagerZFixtureLookupErrorZ
formatreprr   ZoptionZ	fulltrace_pytest_codeZ	Traceback	tracebackrU   r   ZtbstyleverboseosgetcwdOSErrorZgetreprrY   )r!   rT   rZ   Zfmr[   tbr\   rX   r   r   r   _repr_failure_py   sF    



zNode._repr_failure_py)NNNNN)T)N)N)N)N)r%   
__module____qualname____doc__r"   propertyr#   r&   r4   r   r6   r7   r8   r=   rC   rH   rG   rL   rN   rP   rQ   rS   rU   rh   repr_failurer   r   r   r   r   9   s*   
%!



	
-r   c             C   sL   t | dd}|dk	r |dd S t | dd}|dk	r<t|S t | dddfS )a  Tries to extract the actual location from an item, depending on available attributes:

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

    :rtype: a tuple of (str|LocalPath, int) with filename and line number.
    locationN   objr   zunknown locationr
   )r   r   )r<   resultrp   r   r   r   r/   #  s    	r/   c               @   s8   e Zd ZdZG dd deZdd Zdd Zdd	 Zd
S )	Collectorzf Collector instances create children through collect()
        and thus iteratively build a tree.
    c               @   s   e Zd ZdZdS )zCollector.CollectErrorz8 an error during collection, contains a custom message. N)r%   ri   rj   rk   r   r   r   r   CollectError:  s   rs   c             C   s   t ddS )za returns a list of children (items and collectors)
            for this collection node.
        ZabstractN)NotImplementedError)r!   r   r   r   collect=  s    zCollector.collectc             C   s.   | | jr |j}t|jd S | j|ddS )z! represent a collection failure. r   rW   )rZ   )r]   rs   r_   r2   argsrh   )r!   rT   excr   r   r   rm   C  s    zCollector.repr_failurec             C   s@   t | dr<|j}|j| jd}||kr2|jtd}| |_d S )Nr   )r3   )Zexcludepath)hasattrrb   Zcutr   tracebackcutdirfilter)r!   rT   rb   Z
ntracebackr   r   r   rU   J  s    
zCollector._prunetracebackN)	r%   ri   rj   rk   r^   rs   ru   rm   rU   r   r   r   r   rr   5  s
   rr   c             C   s,   x&| j D ]}|||kr||S qW d S )N)Z_initialpathscommonrelto)r   r   Zinitial_pathr   r   r   _check_initialpaths_for_relpathS  s    r}   c                   s   e Zd Zd fdd	Z  ZS )FSCollectorNc                s   t j|}|j}|d k	r<||j}|r.|}|tjt	}|| _|pJ|j
}|d kr| j|jj}|srt||}|rtjt	kr|tjt	}tt| j||||||d d S )N)r   r   )pyr3   localbasenamer|   r   replacerd   sepr   r   r   Zrootdirr}   superr~   r"   )r!   r   r   r   r   r   r   Zrel)r$   r   r   r"   Z  s"    


zFSCollector.__init__)NNNN)r%   ri   rj   r"   __classcell__r   r   )r$   r   r~   Y  s   r~   c               @   s   e Zd ZdZdS )Filez. base class for collecting tests from a file. N)r%   ri   rj   rk   r   r   r   r   r   s  s   r   c                   sB   e Zd ZdZdZd fdd	Zdd Zdd Zed	d
 Z	  Z
S )Itemzv a basic test invocation item. Note that for a single function
    there might be multiple test invocation items.
    Nc                s*   t t| j|||||d g | _g | _d S )N)r   )r   r   r"   _report_sectionsZuser_properties)r!   r   r   r   r   r   )r$   r   r   r"   ~  s    zItem.__init__c             C   s   |r| j |||f dS )a$  
        Adds 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   r9   )r!   ZwhenkeyZcontentr   r   r   add_report_section  s    zItem.add_report_sectionc             C   s   | j d dfS )Nr	   )r   )r!   r   r   r   
reportinfo  s    zItem.reportinfoc             C   sT   y| j S  tk
rN   |  }| j|d }||d t|d f}|| _ |S X d S )Nr   r(   ro   )Z	_locationAttributeErrorr   r   Z_node_location_to_relpathr2   )r!   rn   r   r   r   r   rn     s    zItem.location)NNNN)r%   ri   rj   rk   Znextitemr"   r   r   rl   rn   r   r   r   )r$   r   r   w  s   r   ) Z
__future__r   r   r   rd   r0   r   r@   Z_pytest._coder`   Z_pytest.compatr   Z_pytest.mark.structuresr   Z_pytest.outcomesr   r   r3   r   __file__dirpathry   r   r   objectr   r/   rr   r}   r~   r   r   r   r   r   r   <module>   s,    k