o
    Vh$                     @  s`  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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 ejdk rHd dlmZ nd dlZejd*d
dZej	d+d,ddZd-ddZdd ZeeeZ	 dd Zdd ZejejfddZejee dZejddefd.d"d#Z G d$d% d%Z!G d&d' d'ej"ej#Z"G d(d) d)ej#Z$dS )/    )annotationsN)Iterator)      )tarfiledirstr | os.PathLikereturnIterator[str | os.PathLike]c              	   c  s8    t  }t |  z| V  W t | dS t | w )z
    >>> tmp_path = getfixture('tmp_path')
    >>> with pushd(tmp_path):
    ...     assert os.getcwd() == os.fspath(tmp_path)
    >>> assert os.getcwd() != os.fspath(tmp_path)
    N)osgetcwdchdir)r   orig r   k/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/jaraco/context/__init__.pypushd   s   	
r   
target_dirstr | os.PathLike | Nonec              	   c  s    |du rt j| dddd}t | z/tj| }tj	|dd}|j
|td W d   n1 s8w   Y  |V  W t| dS t| w )au  
    Get a URL to a tarball, download, extract, yield, then clean up.

    Assumes everything in the tarball is prefixed with a common
    directory. That common path is stripped and the contents
    are extracted to ``target_dir``, similar to passing
    ``-C {target} --strip-components 1`` to the ``tar`` command.

    Uses the streaming protocol to extract the contents from a
    stream in a single pass without loading the whole file into
    memory.

    >>> import urllib.request
    >>> url = getfixture('tarfile_served')
    >>> target = getfixture('tmp_path') / 'out'
    >>> tb = tarball(url, target_dir=target)
    >>> import pathlib
    >>> with tb as extracted:
    ...     contents = pathlib.Path(extracted, 'contents.txt').read_text(encoding='utf-8')
    >>> assert not os.path.exists(extracted)

    If the target is not specified, contents are extracted to a
    directory relative to the current working directory named after
    the name of the file as extracted from the URL.

    >>> target = getfixture('tmp_path')
    >>> with pushd(target), tarball(url):
    ...     target.joinpath('served').is_dir()
    True
    Nz.tar.gz z.tgzzr|*)fileobjmode)pathfilter)r   r   basenamereplacemkdirurllibrequesturlopenr   open
extractallstrip_first_componentshutilrmtree)urlr   reqtfr   r   r   tarball)   s   "
r'   membertarfile.TarInfoc                 C  s   | j dd\}| _ | S )N/   )namesplit)r(   r   _r   r   r   r!   W   s   r!   c                  G  s   dd }t |t| S )a  
    Compose any number of dependent context managers into a single one.

    The last, innermost context manager may take arbitrary arguments, but
    each successive context manager should accept the result from the
    previous as a single parameter.

    Like :func:`jaraco.functools.compose`, behavior works from right to
    left, so the context manager should be indicated from outermost to
    innermost.

    Example, to create a context manager to change to a temporary
    directory:

    >>> temp_dir_as_cwd = _compose(pushd, temp_dir)
    >>> with temp_dir_as_cwd() as dir:
    ...     assert os.path.samefile(os.getcwd(), dir)
    c                   s    fdd}t |S )Nc               	   ?  st     | i |(}|}|V  W d    n1 sw   Y  W d    d S W d    d S 1 s3w   Y  d S Nr   )argskwargssavedresinnerouterr   r   composedt   s   Pz/_compose.<locals>.compose_two.<locals>.composed)
contextlibcontextmanager)r5   r6   r7   r   r4   r   compose_twos   s   
z_compose.<locals>.compose_two)	functoolsreducereversed)cmgrsr:   r   r   r   _compose_   s   r?   c                 C  sR   |\}}}| t jt jt jfv r(|jtjkr(t |tjtj	B tj
B  | | dS  )z>
    Add support for removing read-only files on Windows.
    N)r   rmdirremoveunlinkerrnoEACCESchmodstatS_IRWXUS_IRWXGS_IRWXO)funcr   exc_infor.   excr   r   r   remove_readonly   s
   
 rM   c                   C  s"   t  dkrtjtjtdS tjS )NWindows)onerror)platformsystemr;   partialr"   r#   rM   r   r   r   r   robust_remover   s
   rS   c                 c  s*    t  }z
|V  W | | dS | | w )z
    Create a temporary directory context. Pass a custom remover
    to override the removal behavior.

    >>> import pathlib
    >>> with temp_dir() as the_dir:
    ...     assert os.path.isdir(the_dir)
    >>> assert not os.path.exists(the_dir)
    N)tempfilemkdtemp)removertemp_dirr   r   r   rW      s
   rW   )rV   Tbranch
str | Nonequietboolc                 c  s    d| v rdnd}| ,}|d| |g}| d|gt|  |r#tjnd}tj|||d |V  W d   dS 1 s;w   Y  dS )aT  
    Check out the repo indicated by url.

    If dest_ctx is supplied, it should be a context manager
    to yield the target directory for the check out.

    >>> repo = repo_context('https://github.com/jaraco/jaraco.context')
    >>> with repo as dest:
    ...     listing = os.listdir(dest)
    >>> 'README.rst' in listing
    True
    githgclonez--branchN)stdoutstderr)extendr[   
subprocessDEVNULL
check_call)r$   rX   rZ   dest_ctxexerepo_dircmdstreamr   r   r   repo_context   s   "rj   c                   @  st   e Zd ZdZdZeffddZdd Zedd Z	ed	d
 Z
edd Zdd Zdd ZedddZdd ZdS )ExceptionTrapa  
    A context manager that will catch certain exceptions and provide an
    indication they occurred.

    >>> with ExceptionTrap() as trap:
    ...     raise Exception()
    >>> bool(trap)
    True

    >>> with ExceptionTrap() as trap:
    ...     pass
    >>> bool(trap)
    False

    >>> with ExceptionTrap(ValueError) as trap:
    ...     raise ValueError("1 + 1 is not 3")
    >>> bool(trap)
    True
    >>> trap.value
    ValueError('1 + 1 is not 3')
    >>> trap.tb
    <traceback object at ...>

    >>> with ExceptionTrap(ValueError) as trap:
    ...     raise Exception()
    Traceback (most recent call last):
    ...
    Exception

    >>> bool(trap)
    False
    )NNNc                 C  s
   || _ d S r/   )
exceptions)selfrl   r   r   r   __init__      
zExceptionTrap.__init__c                 C     | S r/   r   rm   r   r   r   	__enter__      zExceptionTrap.__enter__c                 C  
   | j d S Nr   rK   rq   r   r   r   type      
zExceptionTrap.typec                 C  rt   )Nr+   rv   rq   r   r   r   value   rx   zExceptionTrap.valuec                 C  rt   )N   rv   rq   r   r   r   tb   rx   zExceptionTrap.tbc                 G  s&   |d }|ot || j}|r|| _|S ru   )
issubclassrl   rK   )rm   rK   rw   matchesr   r   r   __exit__   s
   zExceptionTrap.__exit__c                 C  s
   t | jS r/   )r[   rw   rq   r   r   r   __bool__  ro   zExceptionTrap.__bool___testc                  s   t  fdd}|S )a  
        Wrap func and replace the result with the truth
        value of the trap (True if an exception occurred).

        First, give the decorator an alias to support Python 3.8
        Syntax.

        >>> raises = ExceptionTrap(ValueError).raises

        Now decorate a function that always fails.

        >>> @raises
        ... def fail():
        ...     raise ValueError('failed')
        >>> fail()
        True
        c                    sF   t j}| i | W d     |S 1 sw   Y   |S r/   )rk   rl   )r0   r1   trapr   rJ   rm   r   r   wrapper  s   
z%ExceptionTrap.raises.<locals>.wrapper)r;   wraps)rm   rJ   r   r   r   r   r   raises  s   zExceptionTrap.raisesc                 C  s   | j |tjdS )a  
        Wrap func and replace the result with the truth
        value of the trap (True if no exception).

        First, give the decorator an alias to support Python 3.8
        Syntax.

        >>> passes = ExceptionTrap(ValueError).passes

        Now decorate a function that always fails.

        >>> @passes
        ... def fail():
        ...     raise ValueError('failed')

        >>> fail()
        False
        r   )r   operatornot_)rm   rJ   r   r   r   passes"  s   zExceptionTrap.passesN)__name__
__module____qualname____doc__rK   	Exceptionrn   rr   propertyrw   ry   r{   r~   r   r[   r   r   r   r   r   r   rk      s    !


rk   c                   @  s   e Zd ZdZdS )suppressz
    A version of contextlib.suppress with decorator support.

    >>> @suppress(KeyError)
    ... def key_error():
    ...     {}['']
    >>> key_error()
    N)r   r   r   r   r   r   r   r   r   8  s    r   c                   @  s*   e Zd ZdZdddZdd Zdd	 Zd
S )on_interruptaF  
    Replace a KeyboardInterrupt with SystemExit(1).

    Useful in conjunction with console entry point functions.

    >>> def do_interrupt():
    ...     raise KeyboardInterrupt()
    >>> on_interrupt('error')(do_interrupt)()
    Traceback (most recent call last):
    ...
    SystemExit: 1
    >>> on_interrupt('error', code=255)(do_interrupt)()
    Traceback (most recent call last):
    ...
    SystemExit: 255
    >>> on_interrupt('suppress')(do_interrupt)()
    >>> with __import__('pytest').raises(KeyboardInterrupt):
    ...     on_interrupt('ignore')(do_interrupt)()
    errorr+   c                C  s   || _ || _d S r/   )actioncode)rm   r   r   r   r   r   rn   X  s   
zon_interrupt.__init__c                 C  rp   r/   r   rq   r   r   r   rr   \  rs   zon_interrupt.__enter__c                 C  s6   |t us	| jdkrd S | jdkrt| j|| jdkS )Nignorer   r   )KeyboardInterruptr   
SystemExitr   )rm   exctypeexcinstexctbr   r   r   r~   _  s
   

zon_interrupt.__exit__N)r   r+   )r   r   r   r   rn   rr   r~   r   r   r   r   r   C  s
    
r   )r   r   r	   r
   r/   )r   r   r	   r
   )r(   r)   r	   r)   )rX   rY   rZ   r[   )%
__future__r   r8   rC   r;   r   r   rP   r"   rF   rb   sysrT   urllib.requestr   typingr   version_info	backportsr   r9   r   r'   r!   r?   tarball_cwdrM   rS   r#   rW   rR   robust_temp_dirrj   rk   r   ContextDecoratorr   r   r   r   r   <module>   sJ    

-
q