"""A stash that accesses a zip file."""__author__='Paul Landes'fromtypingimportIterable,UnionfromdataclassesimportdataclassfromzipfileimportZipFilefrompathlibimportPathfrom.importPersistableError,persisted,PersistedWork,ReadOnlyStash
[docs]@dataclass(init=False)classZipStash(ReadOnlyStash):"""Acesss a zip file by using the entry file names as keys and the content of the entries as items. The returned items are either byte arrays if created without an encoding, otherwise decode strings are returned. A root path can be specified so the zip file appears to have been created in a sub-directory. *Implementation note*: keys are cached to speed up access and cleared if the path set on the instance. """
[docs]def__init__(self,path:Path,root:str=None,encoding:str=None):"""See class docs. :param path: the zip file path :param root: the sub-directory in the zip file to base look ups (see class doc) :param encoding: if provided, returned items will be strings decoded with this encoding (such as ``utf-8``) """super().__init__()ifrootisnotNoneand(root.startswith('/')orroot.endswith('/')):raisePersistableError(f"Roots can not start or end with '/': {root}")self._path=pathself._root=rootself._encoding=encodingself._keys=PersistedWork('_keys',self)
@propertydefpath(self)->Path:"""The zip file path."""returnself._path@path.setterdefpath(self,path:Path):"""The zip file path."""self._path=pathself._keys.clear()def_map_name(self,name:str):"""Create an absolute entry name from the item name (key)."""ifself._rootisnotNone:name=self._root+'/'+namereturnname