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.ZipFileA 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.CompleteDirsZipFile 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.PathA 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, andparentresolve to the zipfile. Note these attributes are not valid and will raise aValueErrorif 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#