7
7
for more detail.
8
8
"""
9
9
10
- import functools
10
+ import contextlib
11
11
import io
12
12
import itertools
13
13
import pathlib
17
17
import sys
18
18
import zipfile
19
19
20
- from ._functools import save_method_args
21
20
from .glob import Translator
22
21
23
- __all__ = [' Path' ]
22
+ __all__ = [" Path" ]
24
23
25
24
26
25
def _parents (path ):
@@ -86,12 +85,13 @@ class InitializedState:
86
85
Mix-in to save the initialization state for pickling.
87
86
"""
88
87
89
- @save_method_args
90
88
def __init__ (self , * args , ** kwargs ):
89
+ self .__args = args
90
+ self .__kwargs = kwargs
91
91
super ().__init__ (* args , ** kwargs )
92
92
93
93
def __getstate__ (self ):
94
- return self ._saved___init__ . args , self ._saved___init__ . kwargs
94
+ return self .__args , self .__kwargs
95
95
96
96
def __setstate__ (self , state ):
97
97
args , kwargs = state
@@ -128,7 +128,7 @@ def resolve_dir(self, name):
128
128
as a directory (with the trailing slash).
129
129
"""
130
130
names = self ._name_set ()
131
- dirname = name + '/'
131
+ dirname = name + "/"
132
132
dir_match = name not in names and dirname in names
133
133
return dirname if dir_match else name
134
134
@@ -139,7 +139,7 @@ def getinfo(self, name):
139
139
try :
140
140
return super ().getinfo (name )
141
141
except KeyError :
142
- if not name .endswith ('/' ) or name not in self ._name_set ():
142
+ if not name .endswith ("/" ) or name not in self ._name_set ():
143
143
raise
144
144
return zipfile .ZipInfo (filename = name )
145
145
@@ -156,7 +156,7 @@ def make(cls, source):
156
156
return cls (source )
157
157
158
158
# Only allow for FastLookup when supplied zipfile is read-only
159
- if 'r' not in source .mode :
159
+ if "r" not in source .mode :
160
160
cls = CompleteDirs
161
161
162
162
source .__class__ = cls
@@ -182,21 +182,22 @@ class FastLookup(CompleteDirs):
182
182
def namelist (self ):
183
183
return self ._namelist
184
184
185
- @functools .cached_property
186
- def _namelist (self ):
187
- return super ().namelist ()
185
+ def namelist (self ):
186
+ with contextlib .suppress (AttributeError ):
187
+ return self .__names
188
+ self .__names = super ().namelist ()
189
+ return self .__names
188
190
189
191
def _name_set (self ):
190
- return self ._name_set_prop
191
-
192
- @functools .cached_property
193
- def _name_set_prop (self ):
194
- return super ()._name_set ()
192
+ with contextlib .suppress (AttributeError ):
193
+ return self .__lookup
194
+ self .__lookup = super ()._name_set ()
195
+ return self .__lookup
195
196
196
197
197
198
def _extract_text_encoding (encoding = None , * args , ** kwargs ):
198
199
# compute stack level so that the caller of the caller sees any warning.
199
- is_pypy = sys .implementation .name == ' pypy'
200
+ is_pypy = sys .implementation .name == " pypy"
200
201
# PyPy no longer special cased after 7.3.19 (or maybe 7.3.18)
201
202
# See jaraco/zipp#143
202
203
is_old_pypi = is_pypy and sys .pypy_version_info < (7 , 3 , 19 )
@@ -334,7 +335,7 @@ def __eq__(self, other):
334
335
def __hash__ (self ):
335
336
return hash ((self .root , self .at ))
336
337
337
- def open (self , mode = 'r' , * args , pwd = None , ** kwargs ):
338
+ def open (self , mode = "r" , * args , pwd = None , ** kwargs ):
338
339
"""
339
340
Open this entry as text or binary following the semantics
340
341
of ``pathlib.Path.open()`` by passing arguments through
@@ -343,10 +344,10 @@ def open(self, mode='r', *args, pwd=None, **kwargs):
343
344
if self .is_dir ():
344
345
raise IsADirectoryError (self )
345
346
zip_mode = mode [0 ]
346
- if zip_mode == 'r' and not self .exists ():
347
+ if zip_mode == "r" and not self .exists ():
347
348
raise FileNotFoundError (self )
348
349
stream = self .root .open (self .at , zip_mode , pwd = pwd )
349
- if 'b' in mode :
350
+ if "b" in mode :
350
351
if args or kwargs :
351
352
raise ValueError ("encoding args invalid for binary operation" )
352
353
return stream
@@ -379,11 +380,11 @@ def filename(self):
379
380
380
381
def read_text (self , * args , ** kwargs ):
381
382
encoding , args , kwargs = _extract_text_encoding (* args , ** kwargs )
382
- with self .open ('r' , encoding , * args , ** kwargs ) as strm :
383
+ with self .open ("r" , encoding , * args , ** kwargs ) as strm :
383
384
return strm .read ()
384
385
385
386
def read_bytes (self ):
386
- with self .open ('rb' ) as strm :
387
+ with self .open ("rb" ) as strm :
387
388
return strm .read ()
388
389
389
390
def _is_child (self , path ):
@@ -423,12 +424,12 @@ def glob(self, pattern):
423
424
raise ValueError (f"Unacceptable pattern: { pattern !r} " )
424
425
425
426
prefix = re .escape (self .at )
426
- tr = Translator (seps = '/' )
427
+ tr = Translator (seps = "/" )
427
428
matches = re .compile (prefix + tr .translate (pattern )).fullmatch
428
429
return map (self ._next , filter (matches , self .root .namelist ()))
429
430
430
431
def rglob (self , pattern ):
431
- return self .glob (f' **/{ pattern } ' )
432
+ return self .glob (f" **/{ pattern } " )
432
433
433
434
def relative_to (self , other , * extra ):
434
435
return posixpath .relpath (str (self ), str (other .joinpath (* extra )))
@@ -449,7 +450,7 @@ def joinpath(self, *other):
449
450
def parent (self ):
450
451
if not self .at :
451
452
return self .filename .parent
452
- parent_at = posixpath .dirname (self .at .rstrip ('/' ))
453
+ parent_at = posixpath .dirname (self .at .rstrip ("/" ))
453
454
if parent_at :
454
- parent_at += '/'
455
+ parent_at += "/"
455
456
return self ._next (parent_at )
0 commit comments