JFIFxxC      C  " }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3RbrJFIFxxC      C  " }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr ԓg!.dZddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddl m Z ddl m Z ddlmZdgZdZd Zej(Z d ZGd d ZGd dee j0ZGddeZddZGddZy)z A Path-like interface for zipfiles. This codebase is shared between zipfile.Path in the stdlib and zipp in PyPI. See https://github.com/python/importlib_metadata/wiki/Development-Methodology for more detail. N) text_encoding) Translator)save_method_argsPathcBtjt|ddS)a2 Given a path with elements separated by posixpath.sep, generate all parents of that path. >>> list(_parents('b/d')) ['b'] >>> list(_parents('/b/d/')) ['/b'] >>> list(_parents('b/d/f/')) ['b/d', 'b'] >>> list(_parents('b')) [] >>> list(_parents('')) [] rN) itertoolsislice _ancestry)paths >> list(_ancestry('b/d')) ['b/d', 'b'] >>> list(_ancestry('/b/d/')) ['/b/d', '/b'] >>> list(_ancestry('b/d/f/')) ['b/d/f', 'b/d', 'b'] >>> list(_ancestry('b')) ['b'] >>> list(_ancestry('')) [] Multiple separators are treated like a single. >>> list(_ancestry('//b//d///f//')) ['//b//d///f', '//b//d', '//b'] N)rstrip posixpathsepsplit)r tails r r r 0sS* ;;y}} %D ++imm $ __T* d ++imm $s A:A?=A?cTtjt|j|S)zZ Return items in minuend not in subtrahend, retaining order with O(1) lookup. )r filterfalseset __contains__)minuend subtrahends r _differencerOs!  Z!=!=w GGrc<eZdZdZefdZdZfdZxZS)InitializedStatez? Mix-in to save the initialization state for pickling. c$t||i|yNsuper__init__)selfargskwargs __class__s r r#zInitializedState.__init__\s $)&)rcZ|jj|jjfSr )_saved___init__r%r&r$s r __getstate__zInitializedState.__getstate__`s%##(($*>*>*E*EEErc.|\}}t||i|yr r!)r$stater%r&r's r __setstate__zInitializedState.__setstate__cs f $)&)r) __name__ __module__ __qualname____doc__rr#r+r. __classcell__r's@r rrWs,**F**rrceZdZdZedZfdZdZdZfdZ e dZ e de jd e jfd ZxZS) CompleteDirsa8 A ZipFile subclass that ensures that implied directories are always included in the namelist. >>> list(CompleteDirs._implied_dirs(['foo/bar.txt', 'foo/bar/baz.txt'])) ['foo/', 'foo/bar/'] >>> list(CompleteDirs._implied_dirs(['foo/bar.txt', 'foo/bar/baz.txt', 'foo/bar/'])) ['foo/'] ctjjtt|}d|D}t t ||S)Nc3BK|]}|tjzywr )rr).0ps r z-CompleteDirs._implied_dirs..vs6g1y}}$gs)r chain from_iterablemapr_deduper)namesparentsas_dirss r _implied_dirszCompleteDirs._implied_dirsss9////He0DE6g6{7E233rcZt|}|t|j|zSr )r"namelistlistrC)r$r@r's r rEzCompleteDirs.namelistys+ "tD..u5666rc4t|jSr )rrEr*s r _name_setzCompleteDirs._name_set}s4==?##rcL|j}|dz}||vxr||v}|r|S|S)zx If the name represents a directory, return that name as a directory (with the trailing slash). /)rH)r$namer@dirname dir_matchs r resolve_dirzCompleteDirs.resolve_dirs:  *%:'U*: #w--rc t||S#t$r=|jdr||j vrt j |cYSwxYw)z6 Supplement getinfo for implied dirs. rJ)filename)r"getinfoKeyErrorendswithrHzipfileZipInfo)r$rKr's r rQzCompleteDirs.getinfosR 27?4( ( 2==%T^^5E)E??D1 1 2sAAAct|tr|St|tjs||Sd|jvrt}||_|S)zl Given a source (filename or zipfile), return an appropriate CompleteDirs subclass. r) isinstancer6rTZipFilemoder')clssources r makezCompleteDirs.makesK fl +M&'//2v;  fkk !C rzfreturncr|j|jD]}|j|d|S)z Given a writable zip file zf, inject directory entries for any directories implied by the presence of children. r)rCrEwritestr)r[r^rKs r injectzCompleteDirs.injects2 %%bkkm4D KKc "5 r)r/r0r1r2 staticmethodrCrErHrNrQ classmethodr]rTrYrbr3r4s@r r6r6hsn44 7$. 2$GOOrr6cteZdZdZdZej fdZdZej fdZ xZ S) FastLookupzV ZipFile subclass to ensure implicit dirs exist and are resolved rapidly. c|jSr ) _namelistr*s r rEzFastLookup.namelists ~~rc t|Sr )r"rEr$r's r rhzFastLookup._namelistsw!!rc|jSr )_name_set_propr*s r rHzFastLookup._name_sets"""rc t|Sr )r"rHrjs r rlzFastLookup._name_set_propsw ""r) r/r0r1r2rE functoolscached_propertyrhrHrlr3r4s@r rfrfsF ""###rrfcdtjjdk(}d|z}t||||fS)Npypy)sysimplementationrKr)encodingr%r&is_pypy stack_levels r _extract_text_encodingrxs5  %%/Gg+K ; /v ==rceZdZdZdZd dZdZdZd!dddZd Z e d Z e d Z e d Z e d Ze dZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZeZ e dZ!y)"ru$ A :class:`importlib.resources.abc.Traversable` interface for zip files. Implements many of the features users enjoy from :class:`pathlib.Path`. Consider a zip file with this structure:: . ├── a.txt └── b ├── c.txt └── d └── e.txt >>> data = io.BytesIO() >>> zf = zipfile.ZipFile(data, 'w') >>> zf.writestr('a.txt', 'content of a') >>> zf.writestr('b/c.txt', 'content of c') >>> zf.writestr('b/d/e.txt', 'content of e') >>> zf.filename = 'mem/abcde.zip' Path accepts the zipfile object itself or a filename >>> path = Path(zf) From there, several path operations are available. Directory iteration (including the zip file itself): >>> a, b = path.iterdir() >>> a Path('mem/abcde.zip', 'a.txt') >>> b Path('mem/abcde.zip', 'b/') name property: >>> b.name 'b' join with divide operator: >>> c = b / 'c.txt' >>> c Path('mem/abcde.zip', 'b/c.txt') >>> c.name 'c.txt' Read text: >>> c.read_text(encoding='utf-8') 'content of c' existence: >>> c.exists() True >>> (b / 'missing.txt').exists() False Coercion to string: >>> import os >>> str(c).replace(os.sep, posixpath.sep) 'mem/abcde.zip/b/c.txt' At the root, ``name``, ``filename``, and ``parent`` resolve to the zipfile. >>> str(path) 'mem/abcde.zip/' >>> path.name 'abcde.zip' >>> path.filename == pathlib.Path('mem/abcde.zip') True >>> str(path.parent) 'mem' If the zipfile has no filename, such attributes are not valid and accessing them will raise an Exception. >>> zf.filename = None >>> path.name Traceback (most recent call last): ... TypeError: ... >>> path.filename Traceback (most recent call last): ... TypeError: ... >>> path.parent Traceback (most recent call last): ... TypeError: ... # workaround python/cpython#106763 >>> pass z>{self.__class__.__name__}({self.root.filename!r}, {self.at!r})cFtj||_||_y)aX Construct a Path from a ZipFile or filename. Note: When the source is an existing ZipFile object, its type (__class__) will be mutated to a specialized type. If the caller wishes to retain the original type, the caller should either create a separate ZipFile object or pass a filename. N)rfr]rootat)r$r{r|s r r#z Path.__init__8sOOD) rc|j|jurtS|j|jf|j|jfk(S)zU >>> Path(zipfile.ZipFile(io.BytesIO(), 'w')) == 'foo' False )r'NotImplementedr{r|)r$others r __eq__z Path.__eq__Es? >> 0! ! 477# EHH'===rcDt|j|jfSr )hashr{r|r*s r __hash__z Path.__hash__NsTYY())rNpwdcN|jr t||d}|dk(r|js t||jj |j ||}d|vr|s|r td|St|i|\}}}tj||g|i|S)z Open this entry as text or binary following the semantics of ``pathlib.Path.open()`` by passing arguments through to io.TextIOWrapper(). rrWrbz*encoding args invalid for binary operation) is_dirIsADirectoryErrorexistsFileNotFoundErrorr{openr| ValueErrorrxio TextIOWrapper)r$rZrr%r&zip_modestreamrus r rz Path.openQs ;;=#D) )7 s?4;;=#D) )s; $;v !MNNM!7!H!H$B4B6BBrcptj|jxs|jjSr )pathlib PurePosixPathr|r{rPr*s r _basez Path._basees&$$TWW%B 0B0BCCrc6|jjSr )rrKr*s r rKz Path.namehzz|   rc6|jjSr )rsuffixr*s r rz Path.suffixlszz|"""rc6|jjSr )rsuffixesr*s r rz Path.suffixespszz|$$$rc6|jjSr )rstemr*s r rz Path.stemtrrctj|jjj |j Sr )rrr{rPjoinpathr|r*s r rPz Path.filenamexs*||DII../88AArct|i|\}}}|jd|g|i|5}|jcdddS#1swYyxYw)NrW)rxrread)r$r%r&rustrms r read_textzPath.read_text|sI!7!H!H$ TYYsH 6t 6v 6$99;7 6 6s AA cp|jd5}|jcdddS#1swYyxYw)Nrb)rr)r$rs r read_byteszPath.read_bytess" YYt_99;__s,5ctj|jjd|jjdk(SNrJ)rrLr|r)r$r s r _is_childzPath._is_childs2  !459LLLrc:|j|j|Sr )r'r{)r$r|s r _nextz Path._nexts~~dii,,rcV|j xs|jjdSr)r|rSr*s r rz Path.is_dirs"77{3dgg..s33rcH|jxr|j Sr )rrr*s r is_filez Path.is_files{{}2T[[]!22rcN|j|jjvSr )r|r{rHr*s r rz Path.existssww$))--///rc|js tdt|j|jj }t |j|S)NzCan't listdir a file)rrr>rr{rEfilterr)r$subss r iterdirz Path.iterdirsE{{}34 44::tyy1134dnnd++rc^tj|jj|Sr )rrr|match)r$ path_patterns r rz Path.matchs"$$TWW-33LAArc|jj|j}|jdz }t j |S)z8 Return whether this path is a symlink. )r{rQr| external_attrstatS_ISLNK)r$inforZs r is_symlinkzPath.is_symlinks;yy  )!!R'||D!!rcJ|std|tj|j}t d}tj ||j |zj}t|jt||jjS)NzUnacceptable pattern: rJ)seps) rreescaper|rcompile translate fullmatchr>rrr{rE)r$patternprefixtrmatchess r globz Path.globs{5g[AB B477# S !**Vbll7&;;<FF4::vgtyy/A/A/CDEErc*|jd|S)Nz**/)r)r$rs r rglobz Path.rglobsyy3wi))rcltjt|t|j|Sr )rrelpathstrr)r$rextras r relative_tozPath.relative_tos)  TC0F,GHHrcjtj|jj|jSr )rjoinr{rPr|r*s r __str__z Path.__str__s!~~dii00$''::rc:|jj|S)Nr*) _Path__reprformatr*s r __repr__z Path.__repr__s{{!!t!,,rctj|jg|}|j|jj |Sr )rrr|rr{rN)r$rnexts r rz Path.joinpaths7~~dgg..zz$))//566rc|js|jjStj|jj d}|r|dz }|j |Sr)r|rPparentrrLrr)r$ parent_ats r rz Path.parentsRww=='' '%%dggnnS&9:   Izz)$$r))rW)"r/r0r1r2rr#rrrrpropertyrKrrrrPrrrrrrrrrrrrrrrr __truediv__rrr rrsdLNF >*CC(D!!##%%!!BB M-430, B"F*I;-7K %%rr )r2rnrr rrrrrsrT compat.py310rrr _functoolsr__all__rr dictfromkeysr?rrrYr6rfrxrrrr rs  '( (6&+6 --/H**"H#W__HV##*>x%x%r