8000 gh-135276: Refresh `zipfile.Path` from zipp 3.23 (GH-135277) · python/cpython@dbb0b24 · GitHub
[go: up one dir, main page]

Skip to content

Commit dbb0b24

Browse files
jaracomiss-islington
authored andcommitted
gh-135276: Refresh zipfile.Path from zipp 3.23 (GH-135277)
Apply changes from zipp 3.23 (cherry picked from commit 8d6eb0c) Co-authored-by: Jason R. Coombs <jaraco@jaraco.com>
1 parent cf2209f commit dbb0b24

File tree

8 files changed

+64
-28
lines changed

8 files changed

+64
-28
lines changed

Lib/test/test_zipfile/_path/_test_params.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import types
21
import functools
2+
import types
33

44
from ._itertools import always_iterable
55

Lib/test/test_zipfile/_path/test_complexity.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,8 @@
88

99
from ._functools import compose
1010
from ._itertools import consume
11-
1211
from ._support import import_or_skip
1312

14-
1513
big_o = import_or_skip('big_o')
1614
pytest = import_or_skip('pytest')
1715

Lib/test/test_zipfile/_path/test_path.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1+
import contextlib
12
import io
23
import itertools
3-
import contextlib
44
import pathlib
55
import pickle
66
import stat
@@ -9,12 +9,11 @@
99
import zipfile
1010
import zipfile._path
1111

12-
from test.support.os_helper import temp_dir, FakePath
12+
from test.support.os_helper import FakePath, temp_dir
1313

1414
from ._functools import compose
1515
from ._itertools import Counter
16-
17-
from ._test_params import parameterize, Invoked
16+
from ._test_params import Invoked, parameterize
1817

1918

2019
class jaraco:
@@ -193,10 +192,10 @@ def test_encoding_warnings(self, alpharep):
193192
"""EncodingWarning must blame the read_text and open calls."""
194193
assert sys.flags.warn_default_encoding
195194
root = zipfile.Path(alpharep)
196-
with self.assertWarns(EncodingWarning) as wc:
195+
with self.assertWarns(EncodingWarning) as wc: # noqa: F821 (astral-sh/ruff#13296)
197196
root.joinpath("a.txt").read_text()
198197
assert __file__ == wc.filename
199-
with self.assertWarns(EncodingWarning) as wc:
198+
with self.assertWarns(EncodingWarning) as wc: # noqa: F821 (astral-sh/ruff#13296)
200199
root.joinpath("a.txt").open("r").close()
201200
assert __file__ == wc.filename
202201

@@ -364,6 +363,17 @@ def test_root_name(self, alpharep):
364363
root = zipfile.Path(alpharep)
365364
assert root.name == 'alpharep.zip' == root.filename.name
366365

366+
@pass_alpharep
367+
def test_root_on_disk(self, alpharep):
368+
"""
369+
The name/stem of the root should match the zipfile on disk.
370+
371+
This condition must hold across platforms.
372+
"""
373+
root = zipfile.Path(self.zipfile_ondisk(alpharep))
374+
assert root.name == 'alpharep.zip' == root.filename.name
375+
assert root.stem == 'alpharep' == root.filename.stem
376+
367377
@pass_alpharep
368378
def test_suffix(self, alpharep):
369379
"""
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
from . import test_path
22

3-
43
__name__ == '__main__' and test_path.build_alpharep_fixture().extractall('alpharep')

Lib/zipfile/_path/__init__.py

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,19 @@
77
for more detail.
88
"""
99

10+
import functools
1011
import io
11-
import posixpath
12-
import zipfile
1312
import itertools
14-
import contextlib
1513
import pathlib
14+
import posixpath
1615
import re
1716
import stat
1817
import sys
18+
import zipfile
1919

20+
from ._functools import save_method_args
2021
from .glob import Translator
2122

22-
2323
__all__ = ['Path']
2424

2525

@@ -86,13 +86,12 @@ class InitializedState:
8686
Mix-in to save the initialization state for pickling.
8787
"""
8888

89+
@save_method_args
8990
def __init__(self, *args, **kwargs):
90-
self.__args = args
91-
self.__kwargs = kwargs
9291
super().__init__(*args, **kwargs)
9392

9493
def __getstate__(self):
95-
return self.__args, self.__kwargs
94+
return self._saved___init__.args, self._saved___init__.kwargs
9695

9796
def __setstate__(self, state):
9897
args, kwargs = state
@@ -181,22 +180,27 @@ class FastLookup(CompleteDirs):
181180
"""
182181

183182
def namelist(self):
184-
with contextlib.suppress(AttributeError):
185-
return self.__names
186-
self.__names = super().namelist()
187-
return self.__names
183+
return self._namelist
184+
185+
@functools.cached_property
186+
def _namelist(self):
187+
return super().namelist()
188188

189189
def _name_set(self):
190-
with contextlib.suppress(AttributeError):
191-
return self.__lookup
192-
self.__lookup = super()._name_set()
193-
return self.__lookup
190+
return self._name_set_prop
191+
192+
@functools.cached_property
193+
def _name_set_prop(self):
194+
return super()._name_set()
194195

195196

196197
def _extract_text_encoding(encoding=None, *args, **kwargs):
197198
# compute stack level so that the caller of the caller sees any warning.
198199
is_pypy = sys.implementation.name == 'pypy'
199-
stack_level = 3 + is_pypy
200+
# PyPy no longer special cased after 7.3.19 (or maybe 7.3.18)
201+
# See jaraco/zipp#143
202+
is_old_pypi = is_pypy and sys.pypy_version_info < (7, 3, 19)
203+
stack_level = 3 + is_old_pypi
200204
return io.text_encoding(encoding, stack_level), args, kwargs
201205

202206

@@ -351,7 +355,7 @@ def open(self, mode='r', *args, pwd=None, **kwargs):
351355
return io.TextIOWrapper(stream, encoding, *args, **kwargs)
352356

353357
def _base(self):
354-
return pathlib.PurePosixPath(self.at or self.root.filename)
358+
return pathlib.PurePosixPath(self.at) if self.at else self.filename
355359

356360
@property
357361
def name(self):

Lib/zipfile/_path/_functools.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import collections
2+
import functools
3+
4+
5+
# from jaraco.functools 4.0.2
6+
def save_method_args(method):
7+
"""
8+
Wrap a method such that when it is called, the args and kwargs are
9+
saved on the method.
10+
"""
11+
args_and_kwargs = collections.namedtuple('args_and_kwargs', 'args kwargs') # noqa: PYI024
12+
13+
@functools.wraps(method)
14+
def wrapper(self, /, *args, **kwargs):
15+
attr_name = '_saved_' + method.__name__
16+
attr = args_and_kwargs(args, kwargs)
17+
setattr(self, attr_name, attr)
18+
return method(self, *args, **kwargs)
19+
20+
return wrapper

Lib/zipfile/_path/glob.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import os
22
import re
33

4-
54
_default_seps = os.sep + str(os.altsep) * bool(os.altsep)
65

76

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Synchronized zipfile.Path with zipp 3.23, including improved performance of
2+
:meth:`zipfile.Path.open` for non-reading modes, rely on
3+
:func:`functools.cached_property` to cache values on the instance. Rely on
4+
``save_method_args`` to save the initialization method arguments. Fixed
5+
``.name``, ``.stem`` and other basename-based properties on Windows when
6+
working with a zipfile on disk.

0 commit comments

Comments
 (0)
0