U
    42io,                     @  s   d Z ddlmZ ddlZddlZddlmZ ddl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 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* e*ee+e,f   Z-ed Z.eej/G dd dZ0d d!d"d#Z1d$d%d&d'd(Z2d)d%d*d+d,Z3e!d-d.d/dd0d1d2Z4d/dd3d4d5d6Z5e!d/dd7d8d9d:Z6d;d<d=d>Z7ed?d?d@dAdBdCdDdEZ8dS )Fz>Support for providing temporary directories to test functions.    )annotationsN)Path)rmtree)Any)Dict)final)	Generator)Literal   )cleanup_dead_symlinks)LOCK_TIMEOUT)make_numbered_dir)make_numbered_dir_with_cleanup)rm_rf)get_user_id)Config)ExitCode)hookimpl)Parser)check_ispytest)fixture)FixtureRequest)MonkeyPatch)Item)
TestReport)StashKeyallfailednonec                	   @  s   e Zd ZU dZded< ded< ded< ded< d	ed
< d#ddddd	ddddddZeddddd dddZdddddZd$ddddddZ	dd d!d"Z
dS )%TempPathFactoryzFactory for temporary directories under the common base temp directory,
    as discussed at :ref:`temporary directory location and retention`.
    zPath | None_given_basetempr   _trace	_basetempint_retention_countRetentionType_retention_policyNF	_ispytestboolNone)given_basetempretention_countretention_policybasetempr)   returnc                C  sJ   t | |d krd | _nttjt|| _|| _|| _|| _	|| _
d S N)r   r!   r   ospathabspathstrr"   r%   r'   r#   )selfr,   r-   r.   tracer/   r)    r8   2/tmp/pip-unpacked-wheel-7n2p7kht/_pytest/tmpdir.py__init__7   s    
zTempPathFactory.__init__r   )configr)   r0   c                C  sn   t | t|d}|dk r.td| d|d}|dkrPtd| d| |jj|jd||d	d
S )zTCreate a factory according to pytest configuration.

        :meta private:
        tmp_path_retention_countr   z6tmp_path_retention_count must be >= 0. Current input: .tmp_path_retention_policyr   zKtmp_path_retention_policy must be either all, failed, none. Current input: ZtmpdirT)r,   r7   r-   r.   r)   )r   r$   Zgetini
ValueErroroptionr/   r7   get)clsr;   r)   countpolicyr8   r8   r9   from_configN   s$    



zTempPathFactory.from_configr5   )basenamer0   c                 C  s8   t j|}|  |  j|  kr4t| d|S )Nz& is not a normalized and relative path)r2   r3   normpathgetbasetempresolveparentr?   )r6   rF   r8   r8   r9   _ensure_relative_to_basetempn   s    z,TempPathFactory._ensure_relative_to_basetempTr   )rF   numberedr0   c                 C  sL   |  |}|s*|  |}|jdd nt|  |dd}| d| |S )a  Create a new temporary directory managed by the factory.

        :param basename:
            Directory base name, must be a relative path.

        :param numbered:
            If ``True``, ensure the directory is unique by adding a numbered
            suffix greater than any existing one: ``basename="foo-"`` and ``numbered=True``
            means that this function will create directories named ``"foo-0"``,
            ``"foo-1"``, ``"foo-2"`` and so on.

        :returns:
            The path to the new directory.
          mode)rootprefixrO   mktemp)rK   rH   joinpathmkdirr   r"   )r6   rF   rL   pr8   r8   r9   rR   t   s    
zTempPathFactory.mktempr0   c           	      C  sd  | j dk	r| j S | jdk	rF| j}| r0t| |jdd | }ntjd}t	|p^t
  }t pnd}|d| }z|jddd W n, tk
r   |d	}|jddd Y nX t }|dk	r| }|j|krtd
| d|jd@ dkrt||jd@  | j}| jdkr*d}td||tdd}|dk	sNt||| _ | d| |S )zReturn the base temporary directory, creating it if needed.

        :returns:
            The base temporary directory.
        NrM   rN   ZPYTEST_DEBUG_TEMPROOTunknownz
pytest-of-T)rO   exist_okzpytest-of-unknownzThe temporary directory z: is not owned by the current user. Fix this and try again.?   r   ir   zpytest-)rQ   rP   keepZlock_timeoutrO   znew basetemp)r#   r!   existsr   rT   rI   r2   environrA   r   tempfile
gettempdirget_userrS   OSErrorr   statst_uidst_modechmodr%   r'   r   r   AssertionErrorr"   )	r6   r/   Zfrom_envZtemprootuserrootdiruidZrootdir_statrZ   r8   r8   r9   rH      sP    







zTempPathFactory.getbasetemp)N)T)__name__
__module____qualname____doc____annotations__r:   classmethodrE   rK   rR   rH   r8   r8   r8   r9   r    )   s    
 r    z
str | NonerV   c               
   C  s4   zddl } |  W S  tttfk
r.   Y dS X dS )zlReturn the current user name, or None if getuser() does not work
    in the current environment (see #1010).r   N)getpassgetuserImportErrorr`   KeyError)ro   r8   r8   r9   r_      s
    
r_   r   r+   )r;   r0   c                 C  s6   t  }| |j tj| dd}|j| d|dd dS )a  Create a TempPathFactory and attach it to the config object.

    This is to comply with existing plugins which expect the handler to be
    available at pytest_configure time, but ideally should be moved entirely
    to the tmp_path_factory session fixture.
    Tr(   _tmp_path_factoryF)ZraisingN)r   Zadd_cleanupZundor    rE   setattr)r;   mprs   r8   r8   r9   pytest_configure   s    rv   r   )parserr0   c                 C  s$   | j dddd | j dddd d S )Nr<   zfHow many sessions should we keep the `tmp_path` directories, according to `tmp_path_retention_policy`.   )helpdefaultr>   zvControls which directories created by the `tmp_path` fixture are kept around, based on test outcome. (all/failed/none)r   )Zaddini)rw   r8   r8   r9   pytest_addoption   s    r{   session)Zscoper   )requestr0   c                 C  s   | j jS )zGReturn a :class:`pytest.TempPathFactory` instance for the test session.)r;   rs   )r}   r8   r8   r9   tmp_path_factory   s    r~   r   )r}   factoryr0   c                 C  s4   | j j}tdd|}d}|d | }|j|ddS )Nz[\W]_   T)rL   )nodenameresubrR   )r}   r   r   ZMAXVALr8   r8   r9   _mk_tmp   s
    r   zGenerator[Path])r}   r~   r0   c                 c  sZ   t | |}|V  | jjj}|j}| jjt }|dkrL|ddrLt	|dd | jjt= dS )a;  Return a temporary directory (as :class:`pathlib.Path` object)
    which is unique to each test function invocation.
    The temporary directory is created as a subdirectory
    of the base temporary directory, with configurable retention,
    as discussed in :ref:`temporary directory location and retention`.
    r   callTignore_errorsN)
r   r|   r;   rs   r'   r   stashtmppath_result_keyrA   r   )r}   r~   r3   rD   Zresult_dictr8   r8   r9   tmp_path   s    


r   zint | ExitCode)
exitstatusc                 C  sb   | j j}|j}|dkrdS |j}|dkrN|dkrN|jdkrN| rNt|dd | r^t| dS )zAfter each session, remove base directory if all the tests passed,
    the policy is "failed", and the basetemp is not specified by a user.
    Nr   r   Tr   )r;   rs   r#   r'   r!   is_dirr   r   )r|   r   r~   r/   rD   r8   r8   r9   pytest_sessionfinish  s    r   T)wrapperZtryfirstr   z'Generator[None, TestReport, TestReport])itemr0   c                 c  s2   d V }|j d k	sti }|j| jt||j < |S r1   )whenre   Zpassedr   
setdefaultr   )r   r   repemptyr8   r8   r9   pytest_runtest_makereport2  s
    r   )9rl   
__future__r   Zdataclassesr2   pathlibr   r   shutilr   r]   typingr   r   r   r   r	   r   r   r   r   r   Z_pytest.compatr   Z_pytest.configr   r   r   Z_pytest.config.argparsingr   Z_pytest.deprecatedr   Z_pytest.fixturesr   r   Z_pytest.monkeypatchr   Z_pytest.nodesr   Z_pytest.reportsr   Z_pytest.stashr   r5   r*   r   r&   Z	dataclassr    r_   rv   r{   r~   r   r   r   r   r8   r8   r8   r9   <module>   s\    
