+
    xri&  ã                  óŽ  € ^ 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   "Ú9/usr/lib/python3/dist-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=   é € ô �9Š9‹;€DÜ‡H‚HˆS„MðØŠ	ä
�Š�ŽøŒ�Š��ü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 ÒÜ—W‘W×%Ñ% cÓ*×2Ñ2°9¸bÓA×IÑIÈ&ÐRTÓUˆ
Ü‡H‚HˆZÔð"Ü�n‰n×$Ñ$ SÓ)ˆÜ�\Š\ #¨E×2Õ2°bØ�M‰M˜z´/ˆ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>Y   s   ø€ ¡B¡r¨&Ó'7¸Ô$>r   r   )r2   r3   s   ffr   Úcompose_twoÚ-_compose_tarfile_filters.<locals>.compose_twoX   s	   ù€ Ý>Ð>r   c                ó   € V # r0   r   )r1   r   s   &&r   r4   Ú*_compose_tarfile_filters.<locals>.<lambda>[   s   € Ávr   )Ú	functoolsÚreduce)Úfiltersr6   s   * r   Ú_compose_tarfile_filtersr=   W   s   € ò?ô ×Ò˜KÑ2MÓ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#   € ð —[‘[×&Ñ& s¨AÓ.�N€A„{Ø€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   i   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   € ð �I€AˆAØ”—‘œ"Ÿ)™)¤R§Y¡YÐ/Ô/°C·I±IÄÇÁÔ4Mä
�Š�”t—|‘|¤d§l¡lÕ2´T·\±\Õ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)a0  
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)Úextendrt   Ú
subprocessÚDEVNULLÚ
check_call)r)   rr   rs   Údest_ctxÚexeÚrepo_dirÚcmdÚstreams   &&&&    r   Úrepo_contextr„   ¸   sr   é € ð  ˜C”<‰% T€CÙ	�Œ�xØ�G˜SÐ+ˆØ�
‰
�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.   € Ø˜�{ˆØ×<Ð<œ: d¯O©OÓ<ˆßØ$ŒMØˆr   c                	ó,   € \        V P                  4      # r0   )rt   r”   r�   s   &r   Ú__bool__ÚExceptionTrap.__bool__  s   € Ü�D—I‘I‹Ð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   € ð& �{‰{˜4¤x§}¡}ˆ{Ó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# )ÚsuppressiB  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½   B  s   † õr   r½   c                  ó0   € ] tR tRtRtRR ltR tR tRtR# )	Úon_interruptiM  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__b  s   € ØŒØŽ	r   c                	ó   € V # r0   r   r�   s   &r   rŽ   Úon_interrupt.__enter__f  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__i  sE   € ØÔ+Ó+¨t¯{©{¸hÔ/FÙØ�[‰[˜GÔ#Ü˜TŸY™YÓ'¨WÐ4Ø�{‰{˜jÑ(Ð(r   rÁ   N)rÉ   r˜   )	r´   rµ   r¶   r·   r¸   rŠ   rŽ   r¡   r»   r   r   r   r¿   r¿   M  s   † ñô(òö)r   r¿   )é   é   r0   )(Ú
__future__r   rP   rZ   r:   r°   r   rh   r'   r]   r|   Úsysrm   Úurllib.requestr!   Útypingr   Ú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Ü      sN  ðÝ "ã Û Û Û Û 	Û Û Û Û Û 
Û Û Ý ð ×Ñ�gÔÞ!ãð ×Ñôó ðð  ×Ñö*"ó ð*"òZOõñ +¨7×+>Ñ+>Ð@UÓV€ò:ñ< �u˜gÓ&€ðò
òð ×ÑØ—]‘]ó ó ðð" ×#Ò# H±nÓ6FÔG€ð ×Ñà"°$Àöó ð÷0n6ñ n6ôbˆz×"Ñ" J×$?Ñ$?ô ô!)�:×.Ñ.ö !)r   