summaryrefslogtreecommitdiff
path: root/Lib/zipfile.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/zipfile.py')
-rw-r--r--Lib/zipfile.py25
1 files changed, 19 insertions, 6 deletions
diff --git a/Lib/zipfile.py b/Lib/zipfile.py
index 915698f9e0..da3e40e5db 100644
--- a/Lib/zipfile.py
+++ b/Lib/zipfile.py
@@ -1918,6 +1918,8 @@ class ZipFile:
centDirSize, centDirOffset, len(self._comment))
self.fp.write(endrec)
self.fp.write(self._comment)
+ if self.mode == "a":
+ self.fp.truncate()
self.fp.flush()
def _fpclose(self, fp):
@@ -2195,13 +2197,12 @@ class CompleteDirs(ZipFile):
if not isinstance(source, ZipFile):
return cls(source)
- # Only allow for FastPath when supplied zipfile is read-only
+ # Only allow for FastLookup when supplied zipfile is read-only
if 'r' not in source.mode:
cls = CompleteDirs
- res = cls.__new__(cls)
- vars(res).update(vars(source))
- return res
+ source.__class__ = cls
+ return source
class FastLookup(CompleteDirs):
@@ -2290,17 +2291,29 @@ class Path:
__repr = "{self.__class__.__name__}({self.root.filename!r}, {self.at!r})"
def __init__(self, root, at=""):
+ """
+ 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.
+ """
self.root = FastLookup.make(root)
self.at = at
- def open(self, mode='r', *args, **kwargs):
+ def open(self, mode='r', *args, pwd=None, **kwargs):
"""
Open this entry as text or binary following the semantics
of ``pathlib.Path.open()`` by passing arguments through
to io.TextIOWrapper().
"""
- pwd = kwargs.pop('pwd', None)
+ if self.is_dir():
+ raise IsADirectoryError(self)
zip_mode = mode[0]
+ if not self.exists() and zip_mode == 'r':
+ raise FileNotFoundError(self)
stream = self.root.open(self.at, zip_mode, pwd=pwd)
if 'b' in mode:
if args or kwargs: