|
13 | 13 | import sys |
14 | 14 | import threading |
15 | 15 | import time |
| 16 | +from typing import Self |
16 | 17 |
|
17 | 18 | try: |
18 | 19 | import zlib # We may need its compression method |
@@ -605,6 +606,24 @@ def from_file(cls, filename, arcname=None, *, strict_timestamps=True): |
605 | 606 |
|
606 | 607 | return zinfo |
607 | 608 |
|
| 609 | + def _for_archive(self, archive: ZipFile) -> Self: |
| 610 | + """Resolve suitable defaults from the archive. |
| 611 | +
|
| 612 | + Resolve the date_time, compression attributes, and external attributes |
| 613 | + to suitable defaults as used by :method:`ZipFile.writestr`. |
| 614 | +
|
| 615 | + Return self. |
| 616 | + """ |
| 617 | + self.date_time = time.localtime(time.time())[:6] |
| 618 | + self.compress_type = archive.compression |
| 619 | + self.compress_level = archive.compresslevel |
| 620 | + if self.filename.endswith('/'): # pragma: no cover |
| 621 | + self.external_attr = 0o40775 << 16 # drwxrwxr-x |
| 622 | + self.external_attr |= 0x10 # MS-DOS directory flag |
| 623 | + else: |
| 624 | + self.external_attr = 0o600 << 16 # ?rw------- |
| 625 | + return self |
| 626 | + |
608 | 627 | def is_dir(self): |
609 | 628 | """Return True if this archive member is a directory.""" |
610 | 629 | if self.filename.endswith('/'): |
@@ -1908,18 +1927,10 @@ def writestr(self, zinfo_or_arcname, data, |
1908 | 1927 | the name of the file in the archive.""" |
1909 | 1928 | if isinstance(data, str): |
1910 | 1929 | data = data.encode("utf-8") |
1911 | | - if not isinstance(zinfo_or_arcname, ZipInfo): |
1912 | | - zinfo = ZipInfo(filename=zinfo_or_arcname, |
1913 | | - date_time=time.localtime(time.time())[:6]) |
1914 | | - zinfo.compress_type = self.compression |
1915 | | - zinfo.compress_level = self.compresslevel |
1916 | | - if zinfo.filename.endswith('/'): |
1917 | | - zinfo.external_attr = 0o40775 << 16 # drwxrwxr-x |
1918 | | - zinfo.external_attr |= 0x10 # MS-DOS directory flag |
1919 | | - else: |
1920 | | - zinfo.external_attr = 0o600 << 16 # ?rw------- |
1921 | | - else: |
| 1930 | + if isinstance(zinfo_or_arcname, ZipInfo): |
1922 | 1931 | zinfo = zinfo_or_arcname |
| 1932 | + else: |
| 1933 | + zinfo = ZipInfo(zinfo_or_arcname)._for_archive(self) |
1923 | 1934 |
|
1924 | 1935 | if not self.fp: |
1925 | 1936 | raise ValueError( |
|
0 commit comments