mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-07-30 03:28:31 -07:00
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:
parent
4398dfa821
commit
24fff60ed4
5 changed files with 142 additions and 39 deletions
|
@ -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}')
|
||||
|
|
0
lib/zipp/compat/__init__.py
Normal file
0
lib/zipp/compat/__init__.py
Normal file
112
lib/zipp/glob.py
112
lib/zipp/glob.py
|
@ -1,18 +1,97 @@
|
|||
import os
|
||||
import re
|
||||
|
||||
|
||||
def translate(pattern):
|
||||
r"""
|
||||
Given a glob pattern, produce a regex that matches it.
|
||||
_default_seps = os.sep + str(os.altsep) * bool(os.altsep)
|
||||
|
||||
>>> translate('*.txt')
|
||||
'[^/]*\\.txt'
|
||||
>>> translate('a?txt')
|
||||
'a.txt'
|
||||
>>> translate('**/*')
|
||||
'.*/[^/]*'
|
||||
|
||||
class Translator:
|
||||
"""
|
||||
return ''.join(map(replace, separate(pattern)))
|
||||
>>> 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.
|
||||
|
||||
>>> t = Translator()
|
||||
>>> t.translate_core('*.txt').replace('\\\\', '')
|
||||
'[^/]*\\.txt'
|
||||
>>> t.translate_core('a?txt')
|
||||
'a[^/]txt'
|
||||
>>> t.translate_core('**/*').replace('\\\\', '')
|
||||
'.*/[^/][^/]*'
|
||||
"""
|
||||
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'.')
|
||||
)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue