Qfl*dZddlZddlZddlZddlZddlZddlZddlZddlm Z dgZ dZ dZ e jZ dZGd d ZGd d eej$ZGd deZddZGddZy)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) translatePathcBtjt|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 =/opt/alt/python312/lib64/python3.12/zipfile/_path/__init__.py_parentsr s   IdOQ 55c#K|jtj}|jtjr=|tj|\}}|jtjr>> 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 +sS* ;;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 _differencerJs!  Z!=!=w GGr c2eZdZdZfdZdZfdZxZS)InitializedStatez? Mix-in to save the initialization state for pickling. c@||_||_t| |i|yN)_InitializedState__args_InitializedState__kwargssuper__init__)selfargskwargs __class__s r r"zInitializedState.__init__Ws#   $)&)r c2|j|jfSr)rr r#s r __getstate__zInitializedState.__getstate__\s{{DMM))r c.|\}}t||i|yr)r!r")r#stater$r%r&s r __setstate__zInitializedState.__setstate___s f $)&)r )__name__ __module__ __qualname____doc__r"r)r, __classcell__r&s@r rrRs* ***r rcXeZdZdZedZfdZdZdZfdZ e dZ xZ S) 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..rs6g1y}}$gs)rchain from_iterablemapr _deduper)namesparentsas_dirss r _implied_dirszCompleteDirs._implied_dirsos9////He0DE6g6{7E233r cZt|}|t|j|zSr)r!namelistlistrA)r#r>r&s r rCzCompleteDirs.namelistus+ "tD..u5666r c4t|jSr)rrCr(s r _name_setzCompleteDirs._name_setys4==?##r cL|j}|dz}||vxr||v}|r|S|S)zx If the name represents a directory, return that name as a directory (with the trailing slash). /)rF)r#namer>dirname dir_matchs r resolve_dirzCompleteDirs.resolve_dir|s:  *%:'U*: #w--r c t||S#t$r=|jdr||j vrt j |cYSwxYw)z6 Supplement getinfo for implied dirs. rH)filename)r!getinfoKeyErrorendswithrFzipfileZipInfo)r#rIr&s r rOzCompleteDirs.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) isinstancer4rRZipFilemoder&)clssources r makezCompleteDirs.makesK fl +M&'//2v;  fkk !C r ) r-r.r/r0 staticmethodrArCrFrLrO classmethodr[r1r2s@r r4r4dsD44 7$. 2r r4c,eZdZdZfdZfdZxZS) FastLookupzV ZipFile subclass to ensure implicit dirs exist and are resolved rapidly. ctjt5|jcdddS#1swYnxYwt||_|jSr) contextlibsuppressAttributeError_FastLookup__namesr!rCr#r&s r rCzFastLookup.namelistsB   0<<  0 0w') || 1:ctjt5|jcdddS#1swYnxYwt||_|jSr)rarbrc_FastLookup__lookupr!rFres r rFzFastLookup._name_setsB   0== ! ! 0 0)+ }}rf)r-r.r/r0rCrFr1r2s@r r_r_s  r r_c4tj|d||fS)N)io text_encoding)encodingr$r%s r _extract_text_encodingrns  Ha ($ 66r ceZdZdZdZd 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(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 >>> root = Path(zf) From there, several path operations are available. Directory iteration (including the zip file itself): >>> a, b = root.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. Note these attributes are not valid and will raise a ``ValueError`` if the zipfile has no filename. >>> root.name 'abcde.zip' >>> str(root.filename).replace(os.sep, posixpath.sep) 'mem/abcde.zip' >>> str(root.parent) 'mem' 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)r_r[rootat)r#rqrrs r r"z Path.__init__sOOD) r c|j|jurtS|j|jf|j|jfk(S)zU >>> Path(zipfile.ZipFile(io.BytesIO(), 'w')) == 'foo' False )r&NotImplementedrqrr)r#others r __eq__z Path.__eq__s? >> 0! ! 477# EHH'===r cDt|j|jfSr)hashrqrrr(s r __hash__z Path.__hash__&sTYY())r NpwdcN|jr t||d}|js|dk(r 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(). rrUrzbz*encoding args invalid for binary operation) is_dirIsADirectoryErrorexistsFileNotFoundErrorrqopenrr ValueErrorrnrk TextIOWrapper)r#rXr{r$r%zip_modestreamrms r rz Path.open)s ;;=#D) )7{{}S#D) )s; $;v !MNNM!7!H!H$B4B6BBr cptj|jxs|jjSr)pathlib PurePosixPathrrrqrNr(s r _basez Path._base=s&$$TWW%B 0B0BCCr c6|jjSr)rrIr(s r rIz Path.name@zz|   r c6|jjSr)rsuffixr(s r rz Path.suffixDszz|"""r c6|jjSr)rsuffixesr(s r rz Path.suffixesHszz|$$$r c6|jjSr)rstemr(s r rz Path.stemLrr ctj|jjj |j Sr)rrrqrNjoinpathrrr(s r rNz Path.filenamePs*||DII../88AAr ct|i|\}}}|jd|g|i|5}|jcdddS#1swYyxYw)NrU)rnrread)r#r$r%rmstrms r read_textzPath.read_textTsN!7!H!H$ TYYsH 6t 6v 6$99;   6 6s AA cp|jd5}|jcdddS#1swYyxYw)Nrb)rr)r#rs r read_byteszPath.read_bytesYs' YYt_99;  __s,5ctj|jjd|jjdk(SNrH)rrJrrr)r#r s r _is_childzPath._is_child]s2  !459LLLr c:|j|j|Sr)r&rq)r#rrs r _nextz Path._next`s~~dii,,r cV|j xs|jjdSr)rrrQr(s r r~z Path.is_dircs"77{3dgg..s33r cH|jxr|j Sr)rr~r(s r is_filez Path.is_filefs{{}2T[[]!22r cN|j|jjvSr)rrrqrFr(s r rz Path.existsisww$))--///r c|js tdt|j|jj }t |j|S)NzCan't listdir a file)r~rr<rrqrCfilterr)r#subss r iterdirz Path.iterdirlsE{{}34 44::tyy1134dnnd++r c^tj|jj|Sr)rrrrmatch)r# path_patterns r rz Path.matchrs"$$TWW-33LAAr cy)z] Return whether this path is a symlink. Always false (python/cpython#82102). Fr(s r is_symlinkzPath.is_symlinkusr c&|std|tj|j}tj|t |zj }t|jt||jjS)NzUnacceptable pattern: ) rreescaperrcompiler fullmatchr<rrrqrC)r#patternprefixmatchess r globz Path.glob{sm5g[AB B477#**Vi&889CC4::vgtyy/A/A/CDEEr c*|jd|S)Nz**/)r)r#rs r rglobz Path.rglobsyy3wi))r cltjt|t|j|Sr)rrelpathstrr)r#ruextras r relative_tozPath.relative_tos)  TC0F,GHHr cjtj|jj|jSr)rjoinrqrNrrr(s r __str__z Path.__str__s!~~dii00$''::r c:|jj|S)Nr() _Path__reprformatr(s r __repr__z Path.__repr__s{{!!t!,,r ctj|jg|}|j|jj |Sr)rrrrrrqrL)r#runexts r rz Path.joinpaths7~~dgg..zz$))//566r c|js|jjStj|jj d}|r|dz }|j |Sr)rrrNparentrrJrr)r# parent_ats r rz Path.parentsRww=='' '%%dggnnS&9:   Izz)$$r ))rU)"r-r.r/r0rr"rvryrrpropertyrIrrrrNrrrrr~rrrrrrrrrrr __truediv__rrr r rrsN`NF >*CC(D!!##%%!!BB M-430, B F*I;-7K %%r r)r0rkrrRrrarrrr__all__r r dictfromkeysr=rrrWr4r_rnrrr r rs   (6&+6 --/H**$>#W__>B&7 _%_%r