Bump zipp from 3.16.2 to 3.18.1 (#2281)

* Bump zipp from 3.16.2 to 3.18.1

Bumps [zipp](https://github.com/jaraco/zipp) from 3.16.2 to 3.18.1.
- [Release notes](https://github.com/jaraco/zipp/releases)
- [Changelog](https://github.com/jaraco/zipp/blob/main/NEWS.rst)
- [Commits](https://github.com/jaraco/zipp/compare/v3.16.2...v3.18.1)

---
updated-dependencies:
- dependency-name: zipp
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Update zipp==3.18.1

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: JonnyWong16 <9099342+JonnyWong16@users.noreply.github.com>

[skip ci]
This commit is contained in:
dependabot[bot] 2024-03-24 15:27:03 -07:00 committed by GitHub
parent 4398dfa821
commit 24fff60ed4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 142 additions and 39 deletions

View file

@ -5,9 +5,10 @@ import itertools
import contextlib
import pathlib
import re
import sys
from .py310compat import text_encoding
from .glob import translate
from .compat.py310 import text_encoding
from .glob import Translator
__all__ = ['Path']
@ -148,6 +149,16 @@ class CompleteDirs(InitializedState, zipfile.ZipFile):
source.__class__ = cls
return source
@classmethod
def inject(cls, zf: zipfile.ZipFile) -> zipfile.ZipFile:
"""
Given a writable zip file zf, inject directory entries for
any directories implied by the presence of children.
"""
for name in cls._implied_dirs(zf.namelist()):
zf.writestr(name, b"")
return zf
class FastLookup(CompleteDirs):
"""
@ -169,8 +180,10 @@ class FastLookup(CompleteDirs):
def _extract_text_encoding(encoding=None, *args, **kwargs):
# stacklevel=3 so that the caller of the caller see any warning.
return text_encoding(encoding, 3), args, kwargs
# compute stack level so that the caller of the caller sees any warning.
is_pypy = sys.implementation.name == 'pypy'
stack_level = 3 + is_pypy
return text_encoding(encoding, stack_level), args, kwargs
class Path:
@ -195,13 +208,13 @@ class Path:
Path accepts the zipfile object itself or a filename
>>> root = Path(zf)
>>> path = Path(zf)
From there, several path operations are available.
Directory iteration (including the zip file itself):
>>> a, b = root.iterdir()
>>> a, b = path.iterdir()
>>> a
Path('mem/abcde.zip', 'a.txt')
>>> b
@ -239,16 +252,38 @@ class Path:
'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.
resolve to the zipfile.
>>> root.name
>>> str(path)
'mem/abcde.zip/'
>>> path.name
'abcde.zip'
>>> str(root.filename).replace(os.sep, posixpath.sep)
'mem/abcde.zip'
>>> str(root.parent)
>>> path.filename == pathlib.Path('mem/abcde.zip')
True
>>> str(path.parent)
'mem'
If the zipfile has no filename, such attribtues 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
"""
__repr = "{self.__class__.__name__}({self.root.filename!r}, {self.at!r})"
@ -365,8 +400,10 @@ class Path:
raise ValueError(f"Unacceptable pattern: {pattern!r}")
prefix = re.escape(self.at)
matches = re.compile(prefix + translate(pattern)).fullmatch
return map(self._next, filter(matches, self.root.namelist()))
tr = Translator(seps='/')
matches = re.compile(prefix + tr.translate(pattern)).fullmatch
names = (data.filename for data in self.root.filelist)
return map(self._next, filter(matches, names))
def rglob(self, pattern):
return self.glob(f'**/{pattern}')

View file

View file

@ -1,18 +1,97 @@
import os
import re
def translate(pattern):
_default_seps = os.sep + str(os.altsep) * bool(os.altsep)
class Translator:
"""
>>> Translator('xyz')
Traceback (most recent call last):
...
AssertionError: Invalid separators
>>> Translator('')
Traceback (most recent call last):
...
AssertionError: Invalid separators
"""
seps: str
def __init__(self, seps: str = _default_seps):
assert seps and set(seps) <= set(_default_seps), "Invalid separators"
self.seps = seps
def translate(self, pattern):
"""
Given a glob pattern, produce a regex that matches it.
"""
return self.extend(self.translate_core(pattern))
def extend(self, pattern):
r"""
Extend regex for pattern-wide concerns.
Apply '(?s:)' to create a non-matching group that
matches newlines (valid on Unix).
Append '\Z' to imply fullmatch even when match is used.
"""
return rf'(?s:{pattern})\Z'
def translate_core(self, pattern):
r"""
Given a glob pattern, produce a regex that matches it.
>>> translate('*.txt')
>>> t = Translator()
>>> t.translate_core('*.txt').replace('\\\\', '')
'[^/]*\\.txt'
>>> translate('a?txt')
'a.txt'
>>> translate('**/*')
'.*/[^/]*'
>>> t.translate_core('a?txt')
'a[^/]txt'
>>> t.translate_core('**/*').replace('\\\\', '')
'.*/[^/][^/]*'
"""
return ''.join(map(replace, separate(pattern)))
self.restrict_rglob(pattern)
return ''.join(map(self.replace, separate(self.star_not_empty(pattern))))
def replace(self, match):
"""
Perform the replacements for a match from :func:`separate`.
"""
return match.group('set') or (
re.escape(match.group(0))
.replace('\\*\\*', r'.*')
.replace('\\*', rf'[^{re.escape(self.seps)}]*')
.replace('\\?', r'[^/]')
)
def restrict_rglob(self, pattern):
"""
Raise ValueError if ** appears in anything but a full path segment.
>>> Translator().translate('**foo')
Traceback (most recent call last):
...
ValueError: ** must appear alone in a path segment
"""
seps_pattern = rf'[{re.escape(self.seps)}]+'
segments = re.split(seps_pattern, pattern)
if any('**' in segment and segment != '**' for segment in segments):
raise ValueError("** must appear alone in a path segment")
def star_not_empty(self, pattern):
"""
Ensure that * will not match an empty segment.
"""
def handle_segment(match):
segment = match.group(0)
return '?*' if segment == '*' else segment
not_seps_pattern = rf'[^{re.escape(self.seps)}]+'
return re.sub(not_seps_pattern, handle_segment, pattern)
def separate(pattern):
@ -25,16 +104,3 @@ def separate(pattern):
['a', '[?]', 'txt']
"""
return re.finditer(r'([^\[]+)|(?P<set>[\[].*?[\]])|([\[][^\]]*$)', pattern)
def replace(match):
"""
Perform the replacements for a match from :func:`separate`.
"""
return match.group('set') or (
re.escape(match.group(0))
.replace('\\*\\*', r'.*')
.replace('\\*', r'[^/]*')
.replace('\\?', r'.')
)

View file

@ -49,7 +49,7 @@ urllib3<2
webencodings==0.5.1
websocket-client==1.7.0
xmltodict==0.13.0
zipp==3.16.2
zipp==3.18.1
# configobj==5.1.0
# sgmllib3k==1.0.0