mirror of
https://github.com/python/cpython.git
synced 2025-07-07 19:35:27 +00:00
gh-135276: Refresh zipfile.Path
from zipp 3.23 (#135277)
Apply changes from zipp 3.23
This commit is contained in:
parent
aac22ea212
commit
8d6eb0c262
8 changed files with 64 additions and 28 deletions
|
@ -1,5 +1,5 @@
|
||||||
import types
|
|
||||||
import functools
|
import functools
|
||||||
|
import types
|
||||||
|
|
||||||
from ._itertools import always_iterable
|
from ._itertools import always_iterable
|
||||||
|
|
||||||
|
|
|
@ -8,10 +8,8 @@ import zipfile
|
||||||
|
|
||||||
from ._functools import compose
|
from ._functools import compose
|
||||||
from ._itertools import consume
|
from ._itertools import consume
|
||||||
|
|
||||||
from ._support import import_or_skip
|
from ._support import import_or_skip
|
||||||
|
|
||||||
|
|
||||||
big_o = import_or_skip('big_o')
|
big_o = import_or_skip('big_o')
|
||||||
pytest = import_or_skip('pytest')
|
pytest = import_or_skip('pytest')
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
import contextlib
|
||||||
import io
|
import io
|
||||||
import itertools
|
import itertools
|
||||||
import contextlib
|
|
||||||
import pathlib
|
import pathlib
|
||||||
import pickle
|
import pickle
|
||||||
import stat
|
import stat
|
||||||
|
@ -9,12 +9,11 @@ import unittest
|
||||||
import zipfile
|
import zipfile
|
||||||
import zipfile._path
|
import zipfile._path
|
||||||
|
|
||||||
from test.support.os_helper import temp_dir, FakePath
|
from test.support.os_helper import FakePath, temp_dir
|
||||||
|
|
||||||
from ._functools import compose
|
from ._functools import compose
|
||||||
from ._itertools import Counter
|
from ._itertools import Counter
|
||||||
|
from ._test_params import Invoked, parameterize
|
||||||
from ._test_params import parameterize, Invoked
|
|
||||||
|
|
||||||
|
|
||||||
class jaraco:
|
class jaraco:
|
||||||
|
@ -193,10 +192,10 @@ class TestPath(unittest.TestCase):
|
||||||
"""EncodingWarning must blame the read_text and open calls."""
|
"""EncodingWarning must blame the read_text and open calls."""
|
||||||
assert sys.flags.warn_default_encoding
|
assert sys.flags.warn_default_encoding
|
||||||
root = zipfile.Path(alpharep)
|
root = zipfile.Path(alpharep)
|
||||||
with self.assertWarns(EncodingWarning) as wc:
|
with self.assertWarns(EncodingWarning) as wc: # noqa: F821 (astral-sh/ruff#13296)
|
||||||
root.joinpath("a.txt").read_text()
|
root.joinpath("a.txt").read_text()
|
||||||
assert __file__ == wc.filename
|
assert __file__ == wc.filename
|
||||||
with self.assertWarns(EncodingWarning) as wc:
|
with self.assertWarns(EncodingWarning) as wc: # noqa: F821 (astral-sh/ruff#13296)
|
||||||
root.joinpath("a.txt").open("r").close()
|
root.joinpath("a.txt").open("r").close()
|
||||||
assert __file__ == wc.filename
|
assert __file__ == wc.filename
|
||||||
|
|
||||||
|
@ -364,6 +363,17 @@ class TestPath(unittest.TestCase):
|
||||||
root = zipfile.Path(alpharep)
|
root = zipfile.Path(alpharep)
|
||||||
assert root.name == 'alpharep.zip' == root.filename.name
|
assert root.name == 'alpharep.zip' == root.filename.name
|
||||||
|
|
||||||
|
@pass_alpharep
|
||||||
|
def test_root_on_disk(self, alpharep):
|
||||||
|
"""
|
||||||
|
The name/stem of the root should match the zipfile on disk.
|
||||||
|
|
||||||
|
This condition must hold across platforms.
|
||||||
|
"""
|
||||||
|
root = zipfile.Path(self.zipfile_ondisk(alpharep))
|
||||||
|
assert root.name == 'alpharep.zip' == root.filename.name
|
||||||
|
assert root.stem == 'alpharep' == root.filename.stem
|
||||||
|
|
||||||
@pass_alpharep
|
@pass_alpharep
|
||||||
def test_suffix(self, alpharep):
|
def test_suffix(self, alpharep):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
from . import test_path
|
from . import test_path
|
||||||
|
|
||||||
|
|
||||||
__name__ == '__main__' and test_path.build_alpharep_fixture().extractall('alpharep')
|
__name__ == '__main__' and test_path.build_alpharep_fixture().extractall('alpharep')
|
||||||
|
|
|
@ -7,19 +7,19 @@ https://github.com/python/importlib_metadata/wiki/Development-Methodology
|
||||||
for more detail.
|
for more detail.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import functools
|
||||||
import io
|
import io
|
||||||
import posixpath
|
|
||||||
import zipfile
|
|
||||||
import itertools
|
import itertools
|
||||||
import contextlib
|
|
||||||
import pathlib
|
import pathlib
|
||||||
|
import posixpath
|
||||||
import re
|
import re
|
||||||
import stat
|
import stat
|
||||||
import sys
|
import sys
|
||||||
|
import zipfile
|
||||||
|
|
||||||
|
from ._functools import save_method_args
|
||||||
from .glob import Translator
|
from .glob import Translator
|
||||||
|
|
||||||
|
|
||||||
__all__ = ['Path']
|
__all__ = ['Path']
|
||||||
|
|
||||||
|
|
||||||
|
@ -86,13 +86,12 @@ class InitializedState:
|
||||||
Mix-in to save the initialization state for pickling.
|
Mix-in to save the initialization state for pickling.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@save_method_args
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
self.__args = args
|
|
||||||
self.__kwargs = kwargs
|
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
def __getstate__(self):
|
def __getstate__(self):
|
||||||
return self.__args, self.__kwargs
|
return self._saved___init__.args, self._saved___init__.kwargs
|
||||||
|
|
||||||
def __setstate__(self, state):
|
def __setstate__(self, state):
|
||||||
args, kwargs = state
|
args, kwargs = state
|
||||||
|
@ -181,22 +180,27 @@ class FastLookup(CompleteDirs):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def namelist(self):
|
def namelist(self):
|
||||||
with contextlib.suppress(AttributeError):
|
return self._namelist
|
||||||
return self.__names
|
|
||||||
self.__names = super().namelist()
|
@functools.cached_property
|
||||||
return self.__names
|
def _namelist(self):
|
||||||
|
return super().namelist()
|
||||||
|
|
||||||
def _name_set(self):
|
def _name_set(self):
|
||||||
with contextlib.suppress(AttributeError):
|
return self._name_set_prop
|
||||||
return self.__lookup
|
|
||||||
self.__lookup = super()._name_set()
|
@functools.cached_property
|
||||||
return self.__lookup
|
def _name_set_prop(self):
|
||||||
|
return super()._name_set()
|
||||||
|
|
||||||
|
|
||||||
def _extract_text_encoding(encoding=None, *args, **kwargs):
|
def _extract_text_encoding(encoding=None, *args, **kwargs):
|
||||||
# compute stack level so that the caller of the caller sees any warning.
|
# compute stack level so that the caller of the caller sees any warning.
|
||||||
is_pypy = sys.implementation.name == 'pypy'
|
is_pypy = sys.implementation.name == 'pypy'
|
||||||
stack_level = 3 + is_pypy
|
# PyPy no longer special cased after 7.3.19 (or maybe 7.3.18)
|
||||||
|
# See jaraco/zipp#143
|
||||||
|
is_old_pypi = is_pypy and sys.pypy_version_info < (7, 3, 19)
|
||||||
|
stack_level = 3 + is_old_pypi
|
||||||
return io.text_encoding(encoding, stack_level), args, kwargs
|
return io.text_encoding(encoding, stack_level), args, kwargs
|
||||||
|
|
||||||
|
|
||||||
|
@ -351,7 +355,7 @@ class Path:
|
||||||
return io.TextIOWrapper(stream, encoding, *args, **kwargs)
|
return io.TextIOWrapper(stream, encoding, *args, **kwargs)
|
||||||
|
|
||||||
def _base(self):
|
def _base(self):
|
||||||
return pathlib.PurePosixPath(self.at or self.root.filename)
|
return pathlib.PurePosixPath(self.at) if self.at else self.filename
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
|
|
20
Lib/zipfile/_path/_functools.py
Normal file
20
Lib/zipfile/_path/_functools.py
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
import collections
|
||||||
|
import functools
|
||||||
|
|
||||||
|
|
||||||
|
# from jaraco.functools 4.0.2
|
||||||
|
def save_method_args(method):
|
||||||
|
"""
|
||||||
|
Wrap a method such that when it is called, the args and kwargs are
|
||||||
|
saved on the method.
|
||||||
|
"""
|
||||||
|
args_and_kwargs = collections.namedtuple('args_and_kwargs', 'args kwargs') # noqa: PYI024
|
||||||
|
|
||||||
|
@functools.wraps(method)
|
||||||
|
def wrapper(self, /, *args, **kwargs):
|
||||||
|
attr_name = '_saved_' + method.__name__
|
||||||
|
attr = args_and_kwargs(args, kwargs)
|
||||||
|
setattr(self, attr_name, attr)
|
||||||
|
return method(self, *args, **kwargs)
|
||||||
|
|
||||||
|
return wrapper
|
|
@ -1,7 +1,6 @@
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
|
||||||
_default_seps = os.sep + str(os.altsep) * bool(os.altsep)
|
_default_seps = os.sep + str(os.altsep) * bool(os.altsep)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
Synchronized zipfile.Path with zipp 3.23, including improved performance of
|
||||||
|
:meth:`zipfile.Path.open` for non-reading modes, rely on
|
||||||
|
:func:`functools.cached_property` to cache values on the instance. Rely on
|
||||||
|
``save_method_args`` to save the initialization method arguments. Fixed
|
||||||
|
``.name``, ``.stem`` and other basename-based properties on Windows when
|
||||||
|
working with a zipfile on disk.
|
Loading…
Add table
Add a link
Reference in a new issue