wfexs_backend.utils.zipfile_path
#
Module Contents#
Classes#
A ZipFile subclass that ensures that implied directories are always included in the namelist. |
|
ZipFile subclass to ensure implicit dirs exist and are resolved rapidly. |
|
A pathlib-compatible interface for zip files. |
Functions#
Given a path with elements separated by posixpath.sep, generate all parents of that path. |
|
Given a path with elements separated by posixpath.sep, generate all elements of that path |
|
Return items in minuend not in subtrahend, retaining order with O(1) lookup. |
|
Data#
Deduplicate an iterable in original order |
API#
- wfexs_backend.utils.zipfile_path._parents(path: str) Iterator[str] #
Given a path with elements separated by posixpath.sep, generate all parents of that path.
>>> list(_parents('b/d')) ['b'] >>> list(_parents('/b/d/')) ['/b'] >>> list(_parents('b/d/f/')) ['b/d', 'b'] >>> list(_parents('b')) [] >>> list(_parents('')) []
- wfexs_backend.utils.zipfile_path._ancestry(path: str) Iterator[str] #
Given a path with elements separated by posixpath.sep, generate all elements of that path
>>> list(_ancestry('b/d')) ['b/d', 'b'] >>> list(_ancestry('/b/d/')) ['/b/d', '/b'] >>> list(_ancestry('b/d/f/')) ['b/d/f', 'b/d', 'b'] >>> list(_ancestry('b')) ['b'] >>> list(_ancestry('')) []
- wfexs_backend.utils.zipfile_path._dedupe = None#
Deduplicate an iterable in original order
- wfexs_backend.utils.zipfile_path._difference(minuend: Iterable[str], subtrahend: Iterable[str]) Iterator[str] #
Return items in minuend not in subtrahend, retaining order with O(1) lookup.
- class wfexs_backend.utils.zipfile_path.CompleteDirs(file, mode='r', compression=ZIP_STORED, allowZip64=True, compresslevel=None, *, strict_timestamps=True, metadata_encoding=None)#
Bases:
zipfile.ZipFile
A ZipFile subclass that ensures that implied directories are always included in the namelist.
Initialization
Open the ZIP file with mode read ‘r’, write ‘w’, exclusive create ‘x’, or append ‘a’.
- resolve_dir(name: str) str #
If the name represents a directory, return that name as a directory (with the trailing slash).
- getinfo(name: str) zipfile.ZipInfo #
Supplement getinfo for implied dirs.
- classmethod make(source: CompleteDirs | zipfile.ZipFile | str | os.PathLike[str]) wfexs_backend.utils.zipfile_path.CompleteDirs #
Given a source (filename or zipfile), return an appropriate CompleteDirs subclass.
- class wfexs_backend.utils.zipfile_path.FastLookup(file, mode='r', compression=ZIP_STORED, allowZip64=True, compresslevel=None, *, strict_timestamps=True, metadata_encoding=None)#
Bases:
wfexs_backend.utils.zipfile_path.CompleteDirs
ZipFile subclass to ensure implicit dirs exist and are resolved rapidly.
Initialization
Open the ZIP file with mode read ‘r’, write ‘w’, exclusive create ‘x’, or append ‘a’.
- wfexs_backend.utils.zipfile_path.path_relative_to(path: pathlib.Path, other: pathlib.Path, *extra: str | os.PathLike[str]) str #
- class wfexs_backend.utils.zipfile_path.ZipfilePath(root: str | CompleteDirs | os.PathLike[str] | zipfile.ZipFile, at: str = '')#
Bases:
pathlib.Path
A pathlib-compatible interface for zip files.
Consider a zip file with this structure:
. ├── a.txt └── b ├── c.txt └── d └── e.txt
>>> data = io.BytesIO() >>> zf = zipfile.ZipFile(data, 'w') >>> zf.writestr('a.txt', 'content of a') >>> zf.writestr('b/c.txt', 'content of c') >>> zf.writestr('b/d/e.txt', 'content of e') >>> zf.filename = 'mem/abcde.zip'
Path accepts the zipfile object itself or a filename
>>> root = Path(zf)
From there, several path operations are available.
Directory iteration (including the zip file itself):
>>> a, b = root.iterdir() >>> a Path('mem/abcde.zip', 'a.txt') >>> b Path('mem/abcde.zip', 'b/')
name property:
>>> b.name 'b'
join with divide operator:
>>> c = b / 'c.txt' >>> c Path('mem/abcde.zip', 'b/c.txt') >>> c.name 'c.txt'
Read text:
>>> c.read_text() 'content of c'
existence:
>>> c.exists() True >>> (b / 'missing.txt').exists() False
Coercion to string:
>>> import os >>> str(c).replace(os.sep, posixpath.sep) 'mem/abcde.zip/b/c.txt'
At the root,
name
,filename
, andparent
resolve to the zipfile. Note these attributes are not valid and will raise aValueError
if the zipfile has no filename.>>> root.name 'abcde.zip' >>> str(root.filename).replace(os.sep, posixpath.sep) 'mem/abcde.zip' >>> str(root.parent) 'mem'
Initialization
Construct a Path from a ZipFile or filename.
Note: When the source is an existing ZipFile object, its type (__class__) will be mutated to a specialized type. If the caller wishes to retain the original type, the caller should either create a separate ZipFile object or pass a filename.
- __repr = '{self.__class__.__name__}({self._root.filename!r}, {self._at!r})'#
- __new__(*args: Any, **kwargs: Any) wfexs_backend.utils.zipfile_path.ZipfilePath #
- open(mode: str = 'r', pwd: bytes | None = None, buffering: int = -1, encoding: str | None = None, newline: str | None = None) IO[str] | IO[bytes] #
Open this entry as text or binary following the semantics of
pathlib.Path.open()
by passing arguments through to io.TextIOWrapper().
- property filename: pathlib.Path#
- _is_child(path: wfexs_backend.utils.zipfile_path.ZipfilePath) bool #
- _next(at: str) wfexs_backend.utils.zipfile_path.ZipfilePath #
- iterdir() Generator[ZipfilePath, None, None] #
- joinpath(*other: str | os.PathLike[str]) wfexs_backend.utils.zipfile_path.ZipfilePath #
- __truediv__ = None#
- property parent: wfexs_backend.utils.zipfile_path.ZipfilePath#
- property zip_root: zipfile.ZipFile#
- relative_to(other: str | os.PathLike[str], *_deprecated: str | os.PathLike[str], walk_up: bool = False) pathlib.Path #
- resolve(strict: bool = False) wfexs_backend.utils.zipfile_path.ZipfilePath #
- _extract_member(member: zipfile.ZipInfo | str, targetpath: str | os.PathLike[str], pwd: bytes | None = None, preserve_attrs: bool = True, aggresive_attrs: bool = False) str #
Method partially borrowed from python 3.12
- copy_to(dest: pathlib.Path, preserve_attrs: bool = True, aggresive_attrs: bool = False) None #
- with_name(name: str | os.PathLike[str]) wfexs_backend.utils.zipfile_path.ZipfilePath #