Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-py7zr for openSUSE:Factory 
checked in at 2024-01-04 15:58:18
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-py7zr (Old)
 and      /work/SRC/openSUSE:Factory/.python-py7zr.new.28375 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-py7zr"

Thu Jan  4 15:58:18 2024 rev:8 rq:1136541 version:0.20.8

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-py7zr/python-py7zr.changes        
2023-12-15 21:49:55.583982149 +0100
+++ /work/SRC/openSUSE:Factory/.python-py7zr.new.28375/python-py7zr.changes     
2024-01-04 16:00:32.419407474 +0100
@@ -1,0 +2,8 @@
+Wed Dec 27 13:59:12 UTC 2023 - Dirk Müller <[email protected]>
+
+- update to 0.20.8:
+  * Detect brotli import error (#543)
+  * refactor: hardening SevenZipFile constructor (#547)
+  * refactor: improve type safe functions (#545)
+
+-------------------------------------------------------------------

Old:
----
  py7zr-0.20.7.tar.gz

New:
----
  py7zr-0.20.8.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-py7zr.spec ++++++
--- /var/tmp/diff_new_pack.6BRsRC/_old  2024-01-04 16:00:32.923425886 +0100
+++ /var/tmp/diff_new_pack.6BRsRC/_new  2024-01-04 16:00:32.927426033 +0100
@@ -26,7 +26,7 @@
 %endif
 %{?sle15_python_module_pythons}
 Name:           python-py7zr%{psuffix}
-Version:        0.20.7
+Version:        0.20.8
 Release:        0
 Summary:        Library and utility to support 7zip
 License:        LGPL-2.1-or-later

++++++ py7zr-0.20.7.tar.gz -> py7zr-0.20.8.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/py7zr-0.20.7/.git_archival.txt 
new/py7zr-0.20.8/.git_archival.txt
--- old/py7zr-0.20.7/.git_archival.txt  1970-01-01 01:00:00.000000000 +0100
+++ new/py7zr-0.20.8/.git_archival.txt  2023-11-14 00:22:36.000000000 +0100
@@ -0,0 +1,4 @@
+node: $Format:%H$
+node-date: $Format:%cI$
+describe-name: $Format:%(describe:tags=true,match=*[0-9]*)$
+ref-names: $Format:%D$
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/py7zr-0.20.7/.gitattributes 
new/py7zr-0.20.8/.gitattributes
--- old/py7zr-0.20.7/.gitattributes     1970-01-01 01:00:00.000000000 +0100
+++ new/py7zr-0.20.8/.gitattributes     2023-11-14 00:22:36.000000000 +0100
@@ -0,0 +1 @@
+.git_archival.txt  export-subst
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/py7zr-0.20.7/MANIFEST.in new/py7zr-0.20.8/MANIFEST.in
--- old/py7zr-0.20.7/MANIFEST.in        2023-11-05 23:39:48.000000000 +0100
+++ new/py7zr-0.20.8/MANIFEST.in        2023-11-14 00:22:36.000000000 +0100
@@ -1,6 +1,7 @@
 include *.rst
 include *.svg
 include *.toml
+include *.txt
 include .flake8
 include LICENSE
 include py7zr/py.typed
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/py7zr-0.20.7/PKG-INFO new/py7zr-0.20.8/PKG-INFO
--- old/py7zr-0.20.7/PKG-INFO   2023-11-05 23:40:07.002969000 +0100
+++ new/py7zr-0.20.8/PKG-INFO   2023-11-14 00:22:49.225569700 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: py7zr
-Version: 0.20.7
+Version: 0.20.8
 Summary: Pure python 7-zip library
 Author-email: Hiroshi Miura <[email protected]>
 License: LGPL-2.1-or-later
@@ -62,6 +62,7 @@
 Provides-Extra: check
 Requires-Dist: mypy>=0.940; extra == "check"
 Requires-Dist: mypy_extensions>=0.4.1; extra == "check"
+Requires-Dist: lxml; extra == "check"
 Requires-Dist: types-psutil; extra == "check"
 Requires-Dist: check-manifest; extra == "check"
 Requires-Dist: flake8<7; extra == "check"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/py7zr-0.20.7/docs/Changelog.rst 
new/py7zr-0.20.8/docs/Changelog.rst
--- old/py7zr-0.20.7/docs/Changelog.rst 2023-11-05 23:39:48.000000000 +0100
+++ new/py7zr-0.20.8/docs/Changelog.rst 2023-11-14 00:22:36.000000000 +0100
@@ -9,6 +9,18 @@
 `Unreleased`_
 =============
 
+`v0.20.8`_
+==========
+Fixed
+-----
+* Detect brotli import error (#543)
+
+Changed
+-------
+* refactor: hardening SevenZipFile constructor (#547)
+* refactor: improve type safe functions (#545)
+* chore: add git export configuration (#544)
+
 `v0.20.7`_
 ==========
 Changed
@@ -351,7 +363,8 @@
 
 
 .. History links
-.. _Unreleased: https://github.com/miurahr/py7zr/compare/v0.20.7...HEAD
+.. _Unreleased: https://github.com/miurahr/py7zr/compare/v0.20.8...HEAD
+.. _v0.20.8: https://github.com/miurahr/py7zr/compare/v0.20.7...v0.20.8
 .. _v0.20.7: https://github.com/miurahr/py7zr/compare/v0.20.6...v0.20.7
 .. _v0.20.6: https://github.com/miurahr/py7zr/compare/v0.20.5...v0.20.6
 .. _v0.20.5: https://github.com/miurahr/py7zr/compare/v0.20.4...v0.20.5
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/py7zr-0.20.7/docs/user_guide.rst 
new/py7zr-0.20.8/docs/user_guide.rst
--- old/py7zr-0.20.7/docs/user_guide.rst        2023-11-05 23:39:48.000000000 
+0100
+++ new/py7zr-0.20.8/docs/user_guide.rst        2023-11-14 00:22:36.000000000 
+0100
@@ -24,8 +24,9 @@
     $ pip install py7zr
 
 The py7zr depends on several external libraries. You should install these 
libraries with py7zr.
-There are ``PyCryptodome``, ``PyZstd``, ``PyPPMd``, ``bcj-cffi``, 
``texttable``, and ``multivolumefile``.
-These pakcages are automatically installed when installing with ``pip`` 
command.
+There are `PyCryptodomex`_, `PyZstd`_, `PyPPMd`_, `pybcj`_, `texttable`_, and 
`multivolumefile`_.
+There are also dependency whether `Brotli`_ or `BrotliCFFI`_ depends on your 
python flavour.
+These packages are automatically installed when installing with ``pip`` 
command.
 
 Dependencies
 ------------
@@ -56,6 +57,21 @@
 .. _`multivolumefile` : https://pypi.org/project/multivolumefile
 .. _`texttable` : https://pypi.org/project/texttable
 
+.. note::
+
+    There is known issue when you run ``py7zr`` on Windows platform.
+    `issue#527`_ report that when installed on Azure VM Windows,
+    it failed to import `Brotli`_ library even when ``pip install``
+    was successfully executed. It is because `Brotli`_ library depends
+    ``vc_redist.x64`` Microsoft system library which should be come with
+    python distribution, but Brotli library does not find the DLL in search
+    path on certain environment. Please check details at `Brotli Issue#782`_
+
+    Current ``py7zr`` detect the import failure, and raise exception only when
+    user try to compress/decompress with Brotli compression algorithm.
+
+.. _`issue#527`: https://github.com/miurahr/py7zr/issues/527
+.. _`Brotli Issue#782`: 
https://github.com/google/brotli/issues/782#issuecomment-559516099
 
 
 Run Command
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/py7zr-0.20.7/py7zr/archiveinfo.py 
new/py7zr-0.20.8/py7zr/archiveinfo.py
--- old/py7zr-0.20.7/py7zr/archiveinfo.py       2023-11-05 23:39:48.000000000 
+0100
+++ new/py7zr-0.20.8/py7zr/archiveinfo.py       2023-11-14 00:22:36.000000000 
+0100
@@ -31,7 +31,7 @@
 from io import BytesIO
 from operator import and_, or_
 from struct import pack, unpack
-from typing import Any, BinaryIO, Dict, List, Optional, Tuple
+from typing import Any, BinaryIO, Dict, List, Optional, Tuple, Union
 
 from py7zr.compressor import SevenZipCompressor, SevenZipDecompressor
 from py7zr.exceptions import Bad7zFile
@@ -43,12 +43,27 @@
 P7ZIP_MINOR_VERSION = b"\x04"
 
 
+class WriteWithCrc(io.RawIOBase):
+    """Thin wrapper for file object to calculate crc32 when write called."""
+
+    def __init__(self, fp: BinaryIO):
+        self._fp = fp
+        self.digest = 0
+
+    def write(self, data):
+        self.digest = calculate_crc32(data, self.digest)
+        return self._fp.write(data)
+
+    def tell(self):
+        return self._fp.tell()
+
+
 def read_crcs(file: BinaryIO, count: int) -> List[int]:
     data = file.read(4 * count)
     return [unpack("<L", data[i * 4 : i * 4 + 4])[0] for i in range(count)]
 
 
-def write_crcs(file: BinaryIO, crcs):
+def write_crcs(file: Union[BinaryIO, WriteWithCrc], crcs):
     for crc in crcs:
         write_uint32(file, crc)
 
@@ -57,11 +72,11 @@
     return ord(file.read(1))
 
 
-def write_bytes(file: BinaryIO, data: bytes):
+def write_bytes(file: Union[BinaryIO, WriteWithCrc], data: bytes):
     return file.write(data)
 
 
-def write_byte(file: BinaryIO, data):
+def write_byte(file: Union[BinaryIO, WriteWithCrc], data):
     assert len(data) == 1
     return write_bytes(file, data)
 
@@ -80,7 +95,7 @@
     return a, res
 
 
-def write_uint32(file: BinaryIO, value):
+def write_uint32(file: Union[BinaryIO, WriteWithCrc], value):
     """write uint32 value in 4 bytes."""
     b = pack("<L", value)
     file.write(b)
@@ -116,12 +131,12 @@
     return value + (highpart << (vlen * 8))
 
 
-def write_real_uint64(file: BinaryIO, value: int):
+def write_real_uint64(file: Union[BinaryIO, WriteWithCrc], value: int):
     """write 8 bytes, as an unsigned long long."""
     file.write(pack("<Q", value))
 
 
-def write_uint64(file: BinaryIO, value: int):
+def write_uint64(file: Union[BinaryIO, WriteWithCrc], value: int):
     """
     UINT64 means real UINT64 encoded with the following scheme:
 
@@ -176,7 +191,7 @@
     return result
 
 
-def write_boolean(file: BinaryIO, booleans: List[bool], all_defined: bool = 
False):
+def write_boolean(file: Union[BinaryIO, WriteWithCrc], booleans: List[bool], 
all_defined: bool = False):
     if all_defined and reduce(and_, booleans, True):
         file.write(b"\x01")
         return
@@ -200,7 +215,7 @@
     return val.decode("utf-16LE")
 
 
-def write_utf16(file: BinaryIO, val: str):
+def write_utf16(file: Union[BinaryIO, WriteWithCrc], val: str):
     """write a utf-16 string to file"""
     for c in val:
         file.write(c.encode("utf-16LE"))
@@ -256,7 +271,7 @@
         self.enable_digests = len(self.crcs) > 0
         return self
 
-    def write(self, file: BinaryIO):
+    def write(self, file: Union[BinaryIO, WriteWithCrc]):
         assert self.packpos is not None
         assert self.numstreams == len(self.packsizes)
         write_byte(file, PROPERTY.PACK_INFO)
@@ -506,7 +521,7 @@
                 "end id expected but 0x{:02x} found at 
0x{:08x}".format(ord(pid), file.tell())
             )  # pragma: no-cover  # noqa
 
-    def write(self, file: BinaryIO):
+    def write(self, file: Union[BinaryIO, WriteWithCrc]):
         assert self.numfolders == len(self.folders)
         file.write(PROPERTY.UNPACK_INFO)
         file.write(PROPERTY.FOLDER)
@@ -596,7 +611,7 @@
             self.digestsdefined = [False] * num_digests_total
             self.digests = [0] * num_digests_total
 
-    def write(self, file: BinaryIO):
+    def write(self, file: Union[BinaryIO, WriteWithCrc]):
         if len(self.num_unpackstreams_folders) == 0:  # pragma: no-cover  # 
nothing to write
             return
         write_byte(file, PROPERTY.SUBSTREAMS_INFO)
@@ -654,7 +669,7 @@
         if pid != PROPERTY.END:
             raise Bad7zFile("end id expected but %s found" % repr(pid))  # 
pragma: no-cover
 
-    def write(self, file: BinaryIO):
+    def write(self, file: Union[BinaryIO, WriteWithCrc]):
         write_byte(file, PROPERTY.MAIN_STREAMS_INFO)
         if self.packinfo is not None:
             self.packinfo.write(file)
@@ -676,7 +691,7 @@
         self.unpackinfo: UnpackInfo = UnpackInfo()
         self.unpackinfo.numfolders = 1
 
-    def write(self, file: BinaryIO):
+    def write(self, file: Union[BinaryIO, WriteWithCrc]):
         write_byte(file, PROPERTY.ENCODED_HEADER)
         self.packinfo.write(file)
         self.unpackinfo.write(file)
@@ -776,7 +791,7 @@
         for i, f in enumerate(self.files):
             f["startpos"] = read_real_uint64(fp)[0] if defined[i] else None
 
-    def _write_times(self, fp: BinaryIO, propid, name: str) -> None:
+    def _write_times(self, fp: Union[BinaryIO, WriteWithCrc], propid, name: 
str) -> None:
         write_byte(fp, propid)
         defined = []  # type: List[bool]
         num_defined = 0  # type: int
@@ -799,7 +814,7 @@
             else:
                 pass
 
-    def _write_prop_bool_vector(self, fp: BinaryIO, propid, vector) -> None:
+    def _write_prop_bool_vector(self, fp: Union[BinaryIO, WriteWithCrc], 
propid, vector) -> None:
         write_byte(fp, propid)
         write_boolean(fp, vector, all_defined=False)
 
@@ -810,7 +825,7 @@
                 return True
         return False
 
-    def _write_names(self, file: BinaryIO):
+    def _write_names(self, file: Union[BinaryIO, WriteWithCrc]):
         name_defined = 0
         names = []
         name_size = 0
@@ -846,7 +861,7 @@
             if defined[i]:
                 write_uint32(file, f["attributes"])
 
-    def write(self, file: BinaryIO):
+    def write(self, file: Union[BinaryIO, WriteWithCrc]):
         assert self.files is not None
         write_byte(file, PROPERTY.FILES_INFO)
         numfiles = len(self.files)
@@ -882,21 +897,6 @@
         write_byte(file, PROPERTY.END)
 
 
-class WriteWithCrc:
-    """Thin wrapper for file object to calculate crc32 when write called."""
-
-    def __init__(self, fp: BinaryIO):
-        self._fp = fp
-        self.digest = 0
-
-    def write(self, data):
-        self.digest = calculate_crc32(data, self.digest)
-        return self._fp.write(data)
-
-    def tell(self):
-        return self._fp.tell()
-
-
 class Header:
     """the archive header"""
 
@@ -904,12 +904,13 @@
 
     def __init__(self) -> None:
         self.solid: bool = False
-        self.main_streams = None
-        self.files_info = None
+        self.main_streams: Optional[StreamsInfo] = None
+        self.files_info: Optional[FilesInfo] = None
         self.size: int = 0
         self._start_pos: int = 0
         self.password: Optional[str] = None
         self._initialized: bool = False
+        self.filters: Optional[List[Dict[str, int]]] = None
 
     @classmethod
     def retrieve(cls, fp: BinaryIO, buffer: BytesIO, start_pos: int, 
password=None):
@@ -992,7 +993,7 @@
         # actual header start position
         startpos = file.tell()
         crcfile = WriteWithCrc(file)
-        headerstreams.write(crcfile)  # type: ignore  # noqa
+        headerstreams.write(crcfile)
         digest = crcfile.digest
         return startpos, digest
 
@@ -1006,12 +1007,12 @@
             startpos, headercrc = self._encode_header(file, afterheader, 
filters)
         else:
             crcfile = WriteWithCrc(file)
-            write_byte(crcfile, PROPERTY.HEADER)  # type: ignore  # noqa
+            write_byte(crcfile, PROPERTY.HEADER)
             if self.main_streams is not None:
                 self.main_streams.write(crcfile)
             if self.files_info is not None:
                 self.files_info.write(crcfile)
-            write_byte(crcfile, PROPERTY.END)  # type: ignore
+            write_byte(crcfile, PROPERTY.END)
             headercrc = crcfile.digest
         endpos = file.tell()
         header_len = endpos - startpos
@@ -1043,9 +1044,15 @@
             folder.prepare_coderinfo(self.filters)
             if self.main_streams is not None:
                 # append mode
-                self.main_streams.unpackinfo.folders.append(folder)
-                self.main_streams.unpackinfo.numfolders += 1
-                
self.main_streams.substreamsinfo.num_unpackstreams_folders.append(0)
+                if self.main_streams.unpackinfo is not None:
+                    self.main_streams.unpackinfo.folders.append(folder)
+                    self.main_streams.unpackinfo.numfolders += 1
+                else:
+                    pass  # unexpected
+                if self.main_streams.substreamsinfo is not None:
+                    
self.main_streams.substreamsinfo.num_unpackstreams_folders.append(0)
+                else:
+                    pass  # unexpected
             else:
                 # create new header
                 folders = [folder]
@@ -1069,7 +1076,9 @@
                 self.main_streams.packinfo.crcs = []
             return folder
         else:
-            return self.main_streams.unpackinfo.folders[-1]
+            if self.main_streams is not None and self.main_streams.unpackinfo 
is not None:
+                return self.main_streams.unpackinfo.folders[-1]
+        return None  # unexpected
 
 
 class SignatureHeader:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/py7zr-0.20.7/py7zr/cli.py 
new/py7zr-0.20.8/py7zr/cli.py
--- old/py7zr-0.20.7/py7zr/cli.py       2023-11-05 23:39:48.000000000 +0100
+++ new/py7zr-0.20.8/py7zr/cli.py       2023-11-14 00:22:36.000000000 +0100
@@ -150,7 +150,8 @@
     @staticmethod
     def _get_version():
         s = inspect.stack()
-        module_name = inspect.getmodule(s[0][0]).__name__
+        _module = inspect.getmodule(s[0][0])
+        module_name = _module.__name__ if _module is not None else "unknown"
         py_version = platform.python_version()
         py_impl = platform.python_implementation()
         py_build = platform.python_compiler()
@@ -177,7 +178,7 @@
         table.set_cols_align(["l", "r"])
         for f in SupportedMethods.formats:
             m = "".join(" {:02x}".format(x) for x in f["magic"])
-            table.add_row([f["name"], m])
+            table.add_row([str(f["name"]), m])
         print(table.draw())
         print("\nCodecs and hashes:")
         table = texttable.Texttable()
@@ -185,8 +186,10 @@
         table.set_cols_dtype(["t", "t"])
         table.set_cols_align(["l", "r"])
         for c in SupportedMethods.methods:
-            m = "".join("{:02x}".format(x) for x in c["id"])
-            table.add_row([m, c["name"]])
+            method_id: bytes = c["id"]
+            m = "".join("{:02x}".format(x) for x in method_id)
+            method_name: str = c["name"]
+            table.add_row([m, method_name])
         table.add_row(["0", "CRC32"])
         if is_check_supported(CHECK_SHA256):
             table.add_row(["0", "SHA256"])
@@ -218,10 +221,11 @@
             archive_info = a.archiveinfo()
             archive_list = a.list()
             if verbose:
-                if isinstance(target, io.IOBase):
-                    file.write("Listing archive: {}\n".format(target.name))
+                if isinstance(target, io.FileIO) or isinstance(target, 
multivolumefile.MultiVolume):
+                    file_name: str = target.name  # type: ignore
                 else:
-                    file.write("Listing archive: {}\n".format(str(target)))
+                    file_name = str(target)
+                file.write("Listing archive: {}\n".format(file_name))
                 file.write("--\n")
                 file.write("Path = {}\n".format(archive_info.filename))
                 file.write("Type = 7z\n")
@@ -385,9 +389,12 @@
 
     def _volumesize_unitconv(self, size: str) -> int:
         m = self.unit_pattern.match(size)
-        num = m.group(1)
-        unit = m.group(2)
-        return int(num) if unit is None else int(num) * self.dunits[unit]
+        if m is not None:
+            num = m.group(1)
+            unit = m.group(2)
+            return int(num) if unit is None else int(num) * self.dunits[unit]
+        else:
+            return -1
 
     def run_create(self, args):
         sztarget = args.arcfile  # type: str
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/py7zr-0.20.7/py7zr/compressor.py 
new/py7zr-0.20.8/py7zr/compressor.py
--- old/py7zr-0.20.7/py7zr/compressor.py        2023-11-05 23:39:48.000000000 
+0100
+++ new/py7zr-0.20.8/py7zr/compressor.py        2023-11-14 00:22:36.000000000 
+0100
@@ -66,7 +66,10 @@
 try:
     import brotli  # type: ignore  # noqa
 except ImportError:
-    import brotlicffi as brotli  # type: ignore  # noqa
+    try:
+        import brotlicffi as brotli  # type: ignore  # noqa
+    except ImportError:
+        brotli = None
 brotli_major = 1
 brotli_minor = 0
 
@@ -475,6 +478,11 @@
 
 class BrotliCompressor(ISevenZipCompressor):
     def __init__(self, level):
+        if brotli is None:
+            raise UnsupportedCompressionMethodError(
+                None,
+                "Brotli library load error may be happened. Please check your 
environment have a required system library.",
+            )
         self._compressor = brotli.Compressor(quality=level)
 
     def compress(self, data: Union[bytes, bytearray, memoryview]) -> bytes:
@@ -486,6 +494,11 @@
 
 class BrotliDecompressor(ISevenZipDecompressor):
     def __init__(self, properties: bytes, block_size: int):
+        if brotli is None:
+            raise UnsupportedCompressionMethodError(
+                None,
+                "Brotli library load error may be happened. Please check your 
environment have a required system library.",
+            )
         if len(properties) != 3:
             raise UnsupportedCompressionMethodError(properties, "Unknown size 
of properties are passed")
         if (properties[0], properties[1]) > (brotli_major, brotli_minor):
@@ -549,6 +562,17 @@
 }
 
 
+class LZMA1Compressor(ISevenZipCompressor):
+    def __init__(self, filters):
+        self._compressor = lzma.LZMACompressor(format=lzma.FORMAT_RAW, 
filters=filters)
+
+    def compress(self, data: Union[bytes, bytearray, memoryview]) -> bytes:
+        return self._compressor.compress(data)
+
+    def flush(self) -> bytes:
+        return self._compressor.flush()
+
+
 class LZMA1Decompressor(ISevenZipDecompressor):
     def __init__(self, filters, unpacksize):
         self._decompressor = lzma.LZMADecompressor(format=lzma.FORMAT_RAW, 
filters=filters)
@@ -831,7 +855,7 @@
             raise UnsupportedCompressionMethodError(filters, "Unknown 
combination of methods.")
 
     def _set_native_compressors_coders(self, filters):
-        self.chain.append(lzma.LZMACompressor(format=lzma.FORMAT_RAW, 
filters=filters))
+        self.chain.append(LZMA1Compressor(filters))
         self._unpacksizes.append(0)
         for filter in filters:
             self.coders.insert(0, SupportedMethods.get_coder(filter))
@@ -897,14 +921,16 @@
                 data += compressor.flush()
             else:
                 data = compressor.flush()
+        if data is None:
+            return 0
         self.packsize += len(data)
         self.digest = calculate_crc32(data, self.digest)
         fp.write(data)
         return len(data)
 
     @property
-    def unpacksizes(self):
-        result = []
+    def unpacksizes(self) -> List[int]:
+        result: List[int] = []
         shift = 0
         prev = False
         for i, r in enumerate(self.methods_map):
@@ -923,8 +949,8 @@
 class SupportedMethods:
     """Hold list of methods."""
 
-    formats = [{"name": "7z", "magic": MAGIC_7Z}]
-    methods = [
+    formats: List[Dict[str, Any]] = [{"name": "7z", "magic": MAGIC_7Z}]
+    methods: List[Dict[str, Any]] = [
         {
             "id": COMPRESSION_METHOD.COPY,
             "name": "COPY",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/py7zr-0.20.7/py7zr/py7zr.py 
new/py7zr-0.20.8/py7zr/py7zr.py
--- old/py7zr-0.20.7/py7zr/py7zr.py     2023-11-05 23:39:48.000000000 +0100
+++ new/py7zr-0.20.8/py7zr/py7zr.py     2023-11-14 00:22:36.000000000 +0100
@@ -335,8 +335,12 @@
         blocksize: Optional[int] = None,
         mp: bool = False,
     ) -> None:
+        # check invalid mode.
         if mode not in ("r", "w", "x", "a"):
             raise ValueError("ZipFile requires mode 'r', 'w', 'x', or 'a'")
+        # early check unsupported mode.
+        if mode == "x":
+            raise NotImplementedError
         self.fp: BinaryIO
         self.mp = mp
         self.password_protected = password is not None
@@ -393,15 +397,13 @@
                 self._real_get_contents(password)
                 self.fp.seek(self.afterheader)  # seek into start of payload 
and prepare worker to extract
                 self.worker = Worker(self.files, self.afterheader, 
self.header, self.mp)
-            elif mode in "w":
+            elif mode == "w":
                 self._prepare_write(filters, password)
-            elif mode in "x":
-                raise NotImplementedError
             elif mode == "a":
                 self._real_get_contents(password)
                 self._prepare_append(filters, password)
             else:
-                raise ValueError("Mode must be 'r', 'w', 'x', or 'a'")
+                raise ValueError("Mode must be 'r', 'w', 'x', or 'a'")  # 
never come here
         except Exception as e:
             self._fpclose()
             raise e
@@ -468,21 +470,8 @@
             if not file_info["emptystream"] and folders is not None:
                 folder = folders[pstat.folder]
                 numinstreams = max([coder.get("numinstreams", 1) for coder in 
folder.coders])
-                (
-                    maxsize,
-                    compressed,
-                    uncompressed,
-                    packsize,
-                    solid,
-                ) = self._get_fileinfo_sizes(
-                    pstat,
-                    subinfo,
-                    packinfo,
-                    folder,
-                    packsizes,
-                    unpacksizes,
-                    file_in_solid,
-                    numinstreams,
+                (maxsize, compressed, uncompressed, packsize, solid) = 
self._get_fileinfo_sizes(
+                    pstat, subinfo, packinfo, folder, packsizes, unpacksizes, 
file_in_solid, numinstreams
                 )
                 pstat.input += 1
                 folder.solid = solid
@@ -692,10 +681,11 @@
         self.worker = Worker(self.files, self.afterheader, self.header, 
self.mp)
 
     def _write_flush(self):
-        if self.header._initialized:
-            folder = self.header.main_streams.unpackinfo.folders[-1]
-            self.worker.flush_archive(self.fp, folder)
-        self._write_header()
+        if self.header is not None:
+            if self.header._initialized:
+                folder = self.header.main_streams.unpackinfo.folders[-1]
+                self.worker.flush_archive(self.fp, folder)
+            self._write_header()
 
     def _write_header(self):
         """Write header and update signature header."""
@@ -806,7 +796,7 @@
         return False
 
     def _var_release(self):
-        self._dict = None
+        self._dict = {}
         self.worker.close()
         del self.worker
         del self.files
@@ -1458,12 +1448,12 @@
         Find the target member of a symlink or hardlink member in the archive.
         """
         targetname: str = target.as_posix()
-        linkname = readlink(targetname)
+        linkname: Union[str, pathlib.Path] = readlink(targetname)
         # Check windows full path symlinks
-        if linkname.startswith("\\\\?\\"):
-            linkname = linkname[4:]
+        if str(linkname).startswith("\\\\?\\"):
+            linkname = str(linkname)[4:]
         # normalize as posix style
-        linkname: str = pathlib.Path(linkname).as_posix()
+        linkname = pathlib.Path(linkname).as_posix()
         member = None
         for j in range(len(self.files)):
             if linkname == self.files[j].origin.as_posix():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/py7zr-0.20.7/py7zr/version.py 
new/py7zr-0.20.8/py7zr/version.py
--- old/py7zr-0.20.7/py7zr/version.py   2023-11-05 23:40:06.000000000 +0100
+++ new/py7zr-0.20.8/py7zr/version.py   2023-11-14 00:22:49.000000000 +0100
@@ -1 +1 @@
-__version__ = "0.20.7"
+__version__ = "0.20.8"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/py7zr-0.20.7/py7zr.egg-info/PKG-INFO 
new/py7zr-0.20.8/py7zr.egg-info/PKG-INFO
--- old/py7zr-0.20.7/py7zr.egg-info/PKG-INFO    2023-11-05 23:40:06.000000000 
+0100
+++ new/py7zr-0.20.8/py7zr.egg-info/PKG-INFO    2023-11-14 00:22:49.000000000 
+0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: py7zr
-Version: 0.20.7
+Version: 0.20.8
 Summary: Pure python 7-zip library
 Author-email: Hiroshi Miura <[email protected]>
 License: LGPL-2.1-or-later
@@ -62,6 +62,7 @@
 Provides-Extra: check
 Requires-Dist: mypy>=0.940; extra == "check"
 Requires-Dist: mypy_extensions>=0.4.1; extra == "check"
+Requires-Dist: lxml; extra == "check"
 Requires-Dist: types-psutil; extra == "check"
 Requires-Dist: check-manifest; extra == "check"
 Requires-Dist: flake8<7; extra == "check"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/py7zr-0.20.7/py7zr.egg-info/SOURCES.txt 
new/py7zr-0.20.8/py7zr.egg-info/SOURCES.txt
--- old/py7zr-0.20.7/py7zr.egg-info/SOURCES.txt 2023-11-05 23:40:06.000000000 
+0100
+++ new/py7zr-0.20.8/py7zr.egg-info/SOURCES.txt 2023-11-14 00:22:49.000000000 
+0100
@@ -1,4 +1,6 @@
 .flake8
+.git_archival.txt
+.gitattributes
 LICENSE
 MANIFEST.in
 README.rst
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/py7zr-0.20.7/py7zr.egg-info/requires.txt 
new/py7zr-0.20.8/py7zr.egg-info/requires.txt
--- old/py7zr-0.20.7/py7zr.egg-info/requires.txt        2023-11-05 
23:40:06.000000000 +0100
+++ new/py7zr-0.20.8/py7zr.egg-info/requires.txt        2023-11-14 
00:22:49.000000000 +0100
@@ -21,6 +21,7 @@
 [check]
 mypy>=0.940
 mypy_extensions>=0.4.1
+lxml
 types-psutil
 check-manifest
 flake8<7
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/py7zr-0.20.7/pyproject.toml 
new/py7zr-0.20.8/pyproject.toml
--- old/py7zr-0.20.7/pyproject.toml     2023-11-05 23:39:48.000000000 +0100
+++ new/py7zr-0.20.8/pyproject.toml     2023-11-14 00:22:36.000000000 +0100
@@ -76,6 +76,7 @@
 check = [
       "mypy>=0.940",
       "mypy_extensions>=0.4.1",
+      "lxml",
       "types-psutil",
       "check-manifest",
       "flake8<7",
@@ -139,8 +140,10 @@
 [tool.mypy]
 warn_redundant_casts = true
 warn_unused_ignores = true
+warn_return_any = false
 strict_optional = true
 show_column_numbers = true
+check_untyped_defs = true
 
 [tool.check-manifest]
 ignore = ["py7zr/version.py", "azure-pipelines.yml", ".readthedocs.yml", 
"codecov.yml"]
@@ -205,7 +208,7 @@
 
 [testenv:mypy]
 extras = check
-commands = mypy py7zr
+commands = mypy --html-report build/mypy py7zr
 deps =
     pyzstd
 

Reply via email to