+
    xiQ&                       ^ RI Ht ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RI	t	^ RI
t
^ RIt^ RIt^ RIt^ RIHt ]P"                  R8  d   ^ RIHt M^ RIt]P(                  R R l4       t]P(                  RR R ll4       tR	 tR
 R lt]! ]P2                  ]4      tR t]! ]]4      t R tR t]P(                  ]P>                  3R l4       t ]PB                  ! ] ]! 4       R7      t"]P(                  RR]"3R R ll4       t# ! R R4      t$ ! R R]PJ                  ]PL                  4      t% ! R R]PL                  4      t'R# )    )annotationsN)Iterator)tarfilec                    V ^8  d   QhRRRR/# )   dirzstr | os.PathLikereturnIterator[str | os.PathLike] )formats   "7lib/python3.14/site-packages/jaraco/context/__init__.py__annotate__r      s        %@     c              #     "   \         P                  ! 4       p\         P                  ! V 4        V x  \         P                  ! V4       R#   \         P                  ! T4       i ; i5i)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   origs   & r   pushdr      s=      99;DHHSM	
s   ,A&A A&A##A&c                    V ^8  d   QhRRRR/# )r   
target_dirzstr | os.PathLike | Noner	   r
   r   )r   s   "r   r   r   )   s     *" *"-*" *"r   c              #    "   Vf@   \         P                  P                  V 4      P                  RR4      P                  RR4      p\         P                  ! V4        \
        P                  P                  V 4      p\        P                  ! VRR7      ;_uu_ 4       pVP                  V\        R7       RRR4       Vx  \        P                  ! V4       R#   + '       g   i     L,; i  \        P                  ! T4       i ; i5i)a  
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_default_filtershutilrmtree)urlr   reqtfs   &&  r   tarballr,   (   s     D WW%%c*229bAII&RTU
HHZ"nn$$S)\\#E22bMMz/MB 3j!	 32 	j!s6   AD?C+ C4C+  DC(	#C+ +DDc                 8    R  p\         P                  ! WR 4      # )c                   a a V V3R  l# )c                "   < S! S! W4      V4      # Nr   )memberr   f1f2s   &&r   <lambda>?_compose_tarfile_filters.<locals>.compose_two.<locals>.<lambda>X   s    Br&'7$>r   r   )r2   r3   s   ffr   compose_two-_compose_tarfile_filters.<locals>.compose_twoW   s	    >>r   c                    V # r0   r   )r1   r   s   &&r   r4   *_compose_tarfile_filters.<locals>.<lambda>Z   s    vr   )	functoolsreduce)filtersr6   s   * r   _compose_tarfile_filtersr=   V   s    ? K2MNNr   c                    V ^8  d   QhRRRR/# )r   r1   ztarfile.TarInfor	   r   )r   s   "r   r   r   ]   s       r   c                L    V P                   P                  R ^4      w  q n         V # )/)namesplit)r1   r   _s   && r   strip_first_componentrD   ]   s#     [[&&sA.NA{Mr   c                 H    R p\         P                  ! V\        V 4      4      # )aQ  
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                @   a a V V3R  lp\         P                  ! V4      # )c            	   ?     <"   S! V / VB ;_uu_ 4       pS! V4      ;_uu_ 4       pVx  R R R 4       R R R 4       R #   + '       g   i     L; i  + '       g   i     R # ; i5ir0   r   )argskwargssavedresinnerouters   *,  r   composed/_compose.<locals>.compose_two.<locals>.composed}   s@     '''5%,,#	 3?'',,'''s/   A#A<	A
A#AAA 		A#)
contextlibcontextmanager)rL   rM   rN   s   ff r   r6   _compose.<locals>.compose_two|   s    	 ((22r   )r:   r;   reversed)cmgrsr6   s   * r   _composerU   h   s     (3 K%99r   c                f   Vw  r4pV \         P                  \         P                  \         P                  39   dy   VP                  \        P
                  8X  dZ   \         P                  ! V\        P                  \        P                  ,          \        P                  ,          4       V ! V4       R# h )z6
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_inforC   excs   &&&  r   remove_readonlyrd      se     IAA"))RYY//CII4M
t||dll2T\\ABT
r   c                     \         P                  ! 4       R 8X  d+   \        P                  ! \        P
                  \        R7      # \        P
                  # )Windows)onerror)platformsystemr:   partialr'   r(   rd   r   r   r   robust_removerrk      s<     ??	) 	&--A ]]r   c              #  l   "   \         P                  ! 4       p Vx  V ! V4       R#   T ! T4       i ; i5i)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_dirs   & r   rp   rp      s/      !Hs   4' 
4
14)ro   Tc                    V ^8  d   QhRRRR/# )r   branchz
str | Nonequietboolr   )r   s   "r   r   r      s      +/r   c              #  8  "   RV 9   d   RMRpV! 4       ;_uu_ 4       pVRW.pVP                  RV.\        V4      ,          4       V'       d   \        P                  MRp\        P                  ! WgVR7       Vx  RRR4       R#   + '       g   i     R# ; i5i)an  
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.

>>> getfixture('ensure_git')
>>> getfixture('needs_internet')
>>> 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)extendrt   
subprocessDEVNULL
check_call)r)   rr   rs   dest_ctxexerepo_dircmdstreams   &&&&    r   repo_contextr      sr     $ C<%TC	xGS+

J'$v,67',##$c@ 
s   BAB<
BB		Bc                      ] tR t^tRtRt]33R ltR t]	R 4       t
]	R 4       t]	R 4       tR tR	 tR
]/R ltR tRtR# )ExceptionTrapaA  
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
Nc                	    Wn         R # r0   )
exceptions)selfr   s   &&r   __init__ExceptionTrap.__init__   s    $r   c                	    V # r0   r   r   s   &r   	__enter__ExceptionTrap.__enter__       r   c                	(    V P                   ^ ,          # r   rb   r   s   &r   typeExceptionTrap.type       }}Qr   c                	(    V P                   ^,          # )   r   r   s   &r   valueExceptionTrap.value   r   r   c                	(    V P                   ^,          # )r   r   r   s   &r   tbExceptionTrap.tb  r   r   c                	r    V^ ,          pT;'       d    \        W P                  4      pV'       d   Wn        V# r   )
issubclassr   rb   )r   rb   r   matchess   &*  r   __exit__ExceptionTrap.__exit__  s.    {<<:dOO<$Mr   c                	,    \        V P                  4      # r0   )rt   r   r   s   &r   __bool__ExceptionTrap.__bool__  s    DIIr   _testc               N   a aa \         P                  ! S4      VVV 3R l4       pV# )aQ  
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                    < \        SP                  4      ;_uu_ 4       pS! V / VB  R R R 4       S! X4      #   + '       g   i     L; ir0   )r   r   )rH   rI   trapr   ra   r   s   *, r   wrapper%ExceptionTrap.raises.<locals>.wrapper%  s9    t//4d%f% 0; 0/s	   	8A	)r:   wraps)r   ra   r   r   s   ffd r   raisesExceptionTrap.raises  s'    & 
		 
	
 r   c                D    V P                  V\        P                  R7      # )aJ  
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_)r   ra   s   &&r   passesExceptionTrap.passes-  s    & {{4x}}{55r   )rb   r   )NNN)__name__
__module____qualname____firstlineno____doc__rb   	Exceptionr   r   propertyr   r   r   r   r   rt   r   r   __static_attributes__r   r   r   r   r      su    B  H#,, %            D 66r   r   c                      ] tR tRtRtRtR# )suppressiC  z
A version of contextlib.suppress with decorator support.

>>> @suppress(KeyError)
... def key_error():
...     {}['']
>>> key_error()
r   N)r   r   r   r   r   r   r   r   r   r   r   C  s    r   r   c                  0    ] tR tRtRtRR ltR tR tRtR# )	on_interruptiN  a  
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)()
c               	    Wn         W n        R # r0   actioncode)r   r   r   s   ""&r   r   on_interrupt.__init__c  s    	r   c                	    V # r0   r   r   s   &r   r   on_interrupt.__enter__g  r   r   c                	    V\         Jg   V P                  R 8X  d   R# V P                  R8X  d   \        V P                  4      VhV P                  R8H  # )ignoreNerrorr   )KeyboardInterruptr   
SystemExitr   )r   exctypeexcinstexctbs   &&&&r   r   on_interrupt.__exit__j  sE    ++t{{h/F[[G#TYY'W4{{j((r   r   N)r   r   )	r   r   r   r   r   r   r   r   r   r   r   r   r   r   N  s    ()r   r   )      r0   )(
__future__r   rP   rZ   r:   r   r   rh   r'   r]   r|   sysrm   urllib.requestr!   collections.abcr   version_info	backportsr   rQ   r   r,   r=   rD   data_filterr&   rU   tarball_cwdrd   rk   r(   rp   rj   robust_temp_dirr   r   r   ContextDecoratorr   r   r   r   <module>r      sL   "     	     
   $g!    *" *"ZO +7+>+>@UV:< ug&
 ]]  " ##Hn6FG "$ 4n6 n6bz""J$?$? !):.. !)r   