diff --git a/py7zr/compression.py b/py7zr/compression.py index 690aebef..ae19db33 100644 --- a/py7zr/compression.py +++ b/py7zr/compression.py @@ -48,40 +48,43 @@ def __init__(self, files, src_start: int, header) -> None: self.files = files self.src_start = src_start self.header = header + self._dict = {} # type: Dict[str, IO[Any]] - def extract(self, fp: BinaryIO, parallel: bool) -> None: + def extract(self, fp: BinaryIO, parallel: bool, return_dict: bool = False) -> None: """Extract worker method to handle 7zip folder and decompress each files.""" if hasattr(self.header, 'main_streams') and self.header.main_streams is not None: src_end = self.src_start + self.header.main_streams.packinfo.packpositions[-1] numfolders = self.header.main_streams.unpackinfo.numfolders if numfolders == 1: - self.extract_single(fp, self.files, self.src_start, src_end) + self.extract_single(fp, self.files, self.src_start, src_end, return_dict) else: folders = self.header.main_streams.unpackinfo.folders positions = self.header.main_streams.packinfo.packpositions empty_files = [f for f in self.files if f.emptystream] if not parallel: - self.extract_single(fp, empty_files, 0, 0) + self.extract_single(fp, empty_files, 0, 0, return_dict) for i in range(numfolders): self.extract_single(fp, folders[i].files, self.src_start + positions[i], - self.src_start + positions[i + 1]) + self.src_start + positions[i + 1], return_dict) else: filename = getattr(fp, 'name', None) - self.extract_single(open(filename, 'rb'), empty_files, 0, 0) + self.extract_single(open(filename, 'rb'), empty_files, 0, 0, return_dict) extract_threads = [] for i in range(numfolders): p = threading.Thread(target=self.extract_single, args=(filename, folders[i].files, - self.src_start + positions[i], self.src_start + positions[i + 1])) + self.src_start + positions[i], self.src_start + positions[i + 1], + return_dict)) p.start() extract_threads.append((p)) for p in extract_threads: p.join() else: empty_files = [f for f in self.files if f.emptystream] - self.extract_single(fp, empty_files, 0, 0) + self.extract_single(fp, empty_files, 0, 0, return_dict) - def extract_single(self, fp: Union[BinaryIO, str], files, src_start: int, src_end: int) -> None: + def extract_single(self, fp: Union[BinaryIO, str], files, src_start: int, src_end: int, + return_dict: bool = False) -> None: """Single thread extractor that takes file lists in single 7zip folder.""" if files is None: return @@ -91,12 +94,24 @@ def extract_single(self, fp: Union[BinaryIO, str], files, src_start: int, src_en for f in files: fileish = self.target_filepath.get(f.id, None) if fileish is not None: - with fileish.open(mode='wb') as ofp: + if return_dict: + fname = str(fileish).replace("\\", "/") + self._dict[fname] = io.BytesIO() + ofp = self._dict[fname] if not f.emptystream: # extract to file self.decompress(fp, f.folder, ofp, f.uncompressed[-1], f.compressed, src_end) + ofp.seek(0) else: pass # just create empty file + else: + with fileish.open(mode='wb') as ofp: + if not f.emptystream: + # extract to file + self.decompress(fp, f.folder, ofp, f.uncompressed[-1], f.compressed, src_end) + else: + pass # just create empty file + elif not f.emptystream: # read and bin off a data but check crc with NullIO() as ofp: diff --git a/py7zr/py7zr.py b/py7zr/py7zr.py index ce9fa091..8ae0946b 100644 --- a/py7zr/py7zr.py +++ b/py7zr/py7zr.py @@ -32,7 +32,7 @@ import stat import sys from io import BytesIO -from typing import Any, BinaryIO, Dict, List, Optional, Tuple, Union +from typing import IO, Any, BinaryIO, Dict, List, Optional, Tuple, Union from py7zr.archiveinfo import Folder, Header, SignatureHeader from py7zr.compression import SevenZipCompressor, Worker, get_methods_names @@ -644,15 +644,16 @@ def test(self) -> bool: """Test archive using CRC digests.""" return self._test_digests() - def extractall(self, path: Optional[Any] = None) -> None: + def extractall(self, path: Optional[Any] = None, return_dict: bool = False) -> Optional[Dict[str, IO[Any]]]: """Extract all members from the archive to the current working directory and set owner, modification time and permissions on directories afterwards. `path' specifies a different directory to extract to. """ - return self.extract(path) + return self.extract(path, return_dict=return_dict) - def extract(self, path: Optional[Any] = None, targets: Optional[List[str]] = None) -> None: + def extract(self, path: Optional[Any] = None, targets: Optional[List[str]] = None, + return_dict: bool = False) -> Optional[Dict[str, IO[Any]]]: target_junction = [] # type: List[pathlib.Path] target_sym = [] # type: List[pathlib.Path] target_files = [] # type: List[Tuple[pathlib.Path, Dict[str, Any]]] @@ -724,7 +725,11 @@ def extract(self, path: Optional[Any] = None, targets: Optional[List[str]] = Non raise Exception("Directory name is existed as a normal file.") else: raise Exception("Directory making fails on unknown condition.") - self.worker.extract(self.fp, parallel=(not self.password_protected and not self._filePassed)) + + self.worker.extract(self.fp, parallel=(not self.password_protected and not self._filePassed), + return_dict=return_dict) + if return_dict: + return self.worker._dict # create symbolic links on target path as a working directory. # if path is None, work on current working directory. @@ -746,6 +751,7 @@ def extract(self, path: Optional[Any] = None, targets: Optional[List[str]] = Non for o, p in target_files: self._set_file_property(o, p) + return None def writeall(self, path: Union[pathlib.Path, str], arcname: Optional[str] = None): """Write files in target path into archive.""" diff --git a/tests/__init__.py b/tests/__init__.py index 17b05b0f..fc60a927 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -34,7 +34,7 @@ def decode_all(archive, expected, tmpdir): for i, file_info in enumerate(archive.files): assert file_info.lastwritetime is not None assert file_info.filename is not None - archive.extractall(path=tmpdir) + archive.extractall(path=tmpdir, return_dict=False) archive.close() check_output(expected, tmpdir) diff --git a/tests/test_extract.py b/tests/test_extract.py index 57cf0b02..f6956081 100644 --- a/tests/test_extract.py +++ b/tests/test_extract.py @@ -21,7 +21,7 @@ os.umask(0o022) -def check_archive(archive, tmp_path): +def check_archive(archive, tmp_path, return_dict: bool): assert sorted(archive.getnames()) == ['test', 'test/test2.txt', 'test1.txt'] expected = [] expected.append({'filename': 'test'}) @@ -34,55 +34,81 @@ def check_archive(archive, tmp_path): if not cf.is_directory: assert cf.lastwritetime // 10000000 == expected[i]['lastwritetime'] assert cf.lastwritetime.as_datetime().replace(microsecond=0) == expected[i]['as_datetime'] - archive.extractall(path=tmp_path) - assert tmp_path.joinpath('test/test2.txt').open('rb').read() == bytes('This file is located in a folder.', 'ascii') - assert tmp_path.joinpath('test1.txt').open('rb').read() == bytes('This file is located in the root.', 'ascii') + if not return_dict: + archive.extractall(path=tmp_path, return_dict=return_dict) + assert tmp_path.joinpath('test/test2.txt').open('rb').read() == bytes('This file is located in a folder.', 'ascii') + assert tmp_path.joinpath('test1.txt').open('rb').read() == bytes('This file is located in the root.', 'ascii') + else: + _dict = archive.extractall(return_dict=return_dict) + actual = _dict['test/test2.txt'].read() + assert actual == bytes('This file is located in a folder.', 'ascii') + actual = _dict['test1.txt'].read() + assert actual == bytes('This file is located in the root.', 'ascii') archive.close() @pytest.mark.files -def test_solid(tmp_path): +@pytest.mark.parametrize('return_dict', [False, True]) +def test_solid(tmp_path, return_dict: bool): f = 'solid.7z' archive = py7zr.SevenZipFile(open(os.path.join(testdata_path, '%s' % f), 'rb')) - check_archive(archive, tmp_path) + check_archive(archive, tmp_path, return_dict) @pytest.mark.files -def test_empty(): +@pytest.mark.parametrize('return_dict', [False, True]) +def test_empty(return_dict: bool): # decompress empty archive archive = py7zr.SevenZipFile(open(os.path.join(testdata_path, 'empty.7z'), 'rb')) - assert archive.getnames() == [] + if not return_dict: + assert archive.getnames() == [] + else: + _dict = archive.extractall(return_dict=return_dict) + assert _dict == {} @pytest.mark.files -def test_github_14(tmp_path): +@pytest.mark.parametrize('return_dict', [False, True]) +def test_github_14(tmp_path, return_dict: bool): archive = py7zr.SevenZipFile(open(os.path.join(testdata_path, 'github_14.7z'), 'rb')) - assert archive.getnames() == ['github_14'] - archive.extractall(path=tmp_path) - with tmp_path.joinpath('github_14').open('rb') as f: - assert f.read() == bytes('Hello GitHub issue #14.\n', 'ascii') + if not return_dict: + assert archive.getnames() == ['github_14'] + archive.extractall(path=tmp_path) + with tmp_path.joinpath('github_14').open('rb') as f: + assert f.read() == bytes('Hello GitHub issue #14.\n', 'ascii') + else: + _dict = archive.extractall(return_dict=return_dict) + actual = _dict['github_14'].read() + assert actual == bytes('Hello GitHub issue #14.\n', 'ascii') @pytest.mark.files -def _test_umlaut_archive(filename: str, target: pathlib.Path): +def _test_umlaut_archive(filename: str, target: pathlib.Path, return_dict: bool): archive = py7zr.SevenZipFile(open(os.path.join(testdata_path, filename), 'rb')) - assert sorted(archive.getnames()) == ['t\xe4st.txt'] - archive.extractall(path=target) + if not return_dict: + assert sorted(archive.getnames()) == ['t\xe4st.txt'] + archive.extractall(path=target, return_dict=return_dict) + actual = target.joinpath('t\xe4st.txt').open().read() + assert actual == 'This file contains a german umlaut in the filename.' + else: + _dict = archive.extractall(return_dict=return_dict) + actual = _dict['t\xe4st.txt'].read() + assert actual == b'This file contains a german umlaut in the filename.' archive.close() - actual = target.joinpath('t\xe4st.txt').open().read() - assert actual == 'This file contains a german umlaut in the filename.' @pytest.mark.files -def test_non_solid_umlaut(tmp_path): +@pytest.mark.parametrize('return_dict', [False, True]) +def test_non_solid_umlaut(tmp_path, return_dict: bool): # test loading of a non-solid archive containing files with umlauts - _test_umlaut_archive('umlaut-non_solid.7z', tmp_path) + _test_umlaut_archive('umlaut-non_solid.7z', tmp_path, return_dict) @pytest.mark.files -def test_solid_umlaut(tmp_path): +@pytest.mark.parametrize('return_dict', [False, True]) +def test_solid_umlaut(tmp_path, return_dict: bool): # test loading of a solid archive containing files with umlauts - _test_umlaut_archive('umlaut-solid.7z', tmp_path) + _test_umlaut_archive('umlaut-solid.7z', tmp_path, return_dict) @pytest.mark.files @@ -112,25 +138,36 @@ def test_bugzilla_16(tmp_path): @pytest.mark.files @pytest.mark.skipif(sys.platform.startswith("win") and (ctypes.windll.shell32.IsUserAnAdmin() == 0), reason="Administrator rights is required to make symlink on windows") -def test_extract_symlink(tmp_path): +@pytest.mark.parametrize('return_dict', [False, True]) +def test_extract_symlink(tmp_path, return_dict: bool): archive = py7zr.SevenZipFile(open(os.path.join(testdata_path, 'symlink.7z'), 'rb')) - assert sorted(archive.getnames()) == ['lib', 'lib/libabc.so', 'lib/libabc.so.1', 'lib/libabc.so.1.2', - 'lib/libabc.so.1.2.3', 'lib64'] - archive.extractall(path=tmp_path) + if not return_dict: + assert sorted(archive.getnames()) == ['lib', 'lib/libabc.so', 'lib/libabc.so.1', 'lib/libabc.so.1.2', + 'lib/libabc.so.1.2.3', 'lib64'] + archive.extractall(path=tmp_path, return_dict=return_dict) + else: + _dict = archive.extractall(return_dict=return_dict) archive.close() @pytest.mark.files -def test_lzma2bcj(tmp_path): +@pytest.mark.parametrize('return_dict', [False, True]) +def test_lzma2bcj(tmp_path, return_dict: bool): """Test extract archive compressed with LZMA2 and BCJ methods.""" archive = py7zr.SevenZipFile(open(os.path.join(testdata_path, 'lzma2bcj.7z'), 'rb')) assert archive.getnames() == ['5.12.1', '5.12.1/msvc2017_64', '5.12.1/msvc2017_64/bin', '5.12.1/msvc2017_64/bin/opengl32sw.dll'] - archive.extractall(path=tmp_path) + if not return_dict: + archive.extractall(path=tmp_path, return_dict=return_dict) + m = hashlib.sha256() + m.update(tmp_path.joinpath('5.12.1/msvc2017_64/bin/opengl32sw.dll').open('rb').read()) + assert m.digest() == binascii.unhexlify('963641a718f9cae2705d5299eae9b7444e84e72ab3bef96a691510dd05fa1da4') + else: + _dict = archive.extractall(return_dict=return_dict) + m = hashlib.sha256() + m.update(_dict['5.12.1/msvc2017_64/bin/opengl32sw.dll'].read()) + assert m.digest() == binascii.unhexlify('963641a718f9cae2705d5299eae9b7444e84e72ab3bef96a691510dd05fa1da4') archive.close() - m = hashlib.sha256() - m.update(tmp_path.joinpath('5.12.1/msvc2017_64/bin/opengl32sw.dll').open('rb').read()) - assert m.digest() == binascii.unhexlify('963641a718f9cae2705d5299eae9b7444e84e72ab3bef96a691510dd05fa1da4') @pytest.mark.files @@ -141,15 +178,23 @@ def test_extract_lzmabcj_archiveinfo(): @pytest.mark.files @pytest.mark.xfail(reason="Uknown problem that it become no data exception.") -def test_extract_lzmabcj(tmp_path): +@pytest.mark.parametrize('return_dict', [False, True]) +def test_extract_lzmabcj(tmp_path, return_dict: bool): with py7zr.SevenZipFile(os.path.join(testdata_path, 'lzmabcj.7z'), 'r') as ar: - ar.extractall(path=tmp_path) + if not return_dict: + ar.extractall(path=tmp_path, return_dict=return_dict) + else: + _dict = ar.extractall(return_dict=return_dict) @pytest.mark.files -def test_zerosize(tmp_path): +@pytest.mark.parametrize('return_dict', [False, True]) +def test_zerosize(tmp_path, return_dict: bool): archive = py7zr.SevenZipFile(open(os.path.join(testdata_path, 'zerosize.7z'), 'rb')) - archive.extractall(path=tmp_path) + if not return_dict: + archive.extractall(path=tmp_path, return_dict=return_dict) + else: + _dict = archive.extractall(return_dict=return_dict) archive.close() @@ -185,69 +230,104 @@ def test_skip(): @pytest.mark.files -def test_github_14_multi(tmp_path): +@pytest.mark.parametrize('return_dict', [False, True]) +def test_github_14_multi(tmp_path, return_dict: bool): """ multiple unnamed objects.""" archive = py7zr.SevenZipFile(os.path.join(testdata_path, 'github_14_multi.7z'), 'r') assert archive.getnames() == ['github_14_multi', 'github_14_multi'] - archive.extractall(path=tmp_path) + if not return_dict: + archive.extractall(path=tmp_path, return_dict=return_dict) + with tmp_path.joinpath('github_14_multi').open('rb') as f: + assert f.read() == bytes('Hello GitHub issue #14 1/2.\n', 'ascii') + with tmp_path.joinpath('github_14_multi_0').open('rb') as f: + assert f.read() == bytes('Hello GitHub issue #14 2/2.\n', 'ascii') + else: + _dict = archive.extractall(return_dict=return_dict) + actual_1 = _dict['github_14_multi'].read() + assert actual_1 == bytes('Hello GitHub issue #14 1/2.\n', 'ascii') + actual_2 = _dict['github_14_multi_0'].read() + assert actual_2 == bytes('Hello GitHub issue #14 2/2.\n', 'ascii') archive.close() - with tmp_path.joinpath('github_14_multi').open('rb') as f: - assert f.read() == bytes('Hello GitHub issue #14 1/2.\n', 'ascii') - with tmp_path.joinpath('github_14_multi_0').open('rb') as f: - assert f.read() == bytes('Hello GitHub issue #14 2/2.\n', 'ascii') @pytest.mark.files -def test_multiblock(tmp_path): +@pytest.mark.parametrize('return_dict', [False, True]) +def test_multiblock(tmp_path, return_dict: bool): archive = py7zr.SevenZipFile(open(os.path.join(testdata_path, 'mblock_1.7z'), 'rb')) - archive.extractall(path=tmp_path) + if not return_dict: + archive.extractall(path=tmp_path, return_dict=return_dict) + m = hashlib.sha256() + m.update(tmp_path.joinpath('bin/7zdec.exe').open('rb').read()) + assert m.digest() == binascii.unhexlify('e14d8201c5c0d1049e717a63898a3b1c7ce4054a24871daebaa717da64dcaff5') + else: + _dict = archive.extractall(return_dict=return_dict) + m = hashlib.sha256() + m.update(_dict["bin/7zdec.exe"].read()) + assert m.digest() == binascii.unhexlify('e14d8201c5c0d1049e717a63898a3b1c7ce4054a24871daebaa717da64dcaff5') archive.close() - m = hashlib.sha256() - m.update(tmp_path.joinpath('bin/7zdec.exe').open('rb').read()) - assert m.digest() == binascii.unhexlify('e14d8201c5c0d1049e717a63898a3b1c7ce4054a24871daebaa717da64dcaff5') @pytest.mark.files @pytest.mark.skipif(sys.platform.startswith('win'), reason="Cannot unlink opened file on Windows") -def test_multiblock_unlink(tmp_path): +@pytest.mark.parametrize('return_dict', [False, True]) +def test_multiblock_unlink(tmp_path, return_dict: bool): """When passing opened file object, even after unlink it should work.""" shutil.copy(os.path.join(testdata_path, 'mblock_1.7z'), str(tmp_path)) src = tmp_path.joinpath('mblock_1.7z') archive = py7zr.SevenZipFile(open(str(src), 'rb')) - os.unlink(str(src)) - archive.extractall(path=tmp_path) + if not return_dict: + os.unlink(str(src)) + archive.extractall(path=tmp_path, return_dict=return_dict) + else: + _dict = archive.extractall(return_dict=return_dict) archive.close() @pytest.mark.files -def test_multiblock_zerosize(tmp_path): +@pytest.mark.parametrize('return_dict', [False, True]) +def test_multiblock_zerosize(tmp_path, return_dict: bool): archive = py7zr.SevenZipFile(open(os.path.join(testdata_path, 'mblock_2.7z'), 'rb')) - archive.extractall(path=tmp_path) + if not return_dict: + archive.extractall(path=tmp_path, return_dict=return_dict) + else: + _dict = archive.extractall(return_dict=return_dict) archive.close() @pytest.mark.files @pytest.mark.timeout(10, method='thread') -def test_multiblock_lzma_bug(tmp_path): +@pytest.mark.parametrize('return_dict', [False, True]) +def test_multiblock_lzma_bug(tmp_path, return_dict: bool): archive = py7zr.SevenZipFile(open(os.path.join(testdata_path, 'mblock_3.7z'), 'rb')) - archive.extractall(path=tmp_path) + if not return_dict: + archive.extractall(path=tmp_path, return_dict=return_dict) + m = hashlib.sha256() + m.update(tmp_path.joinpath('5.13.0/mingw73_64/plugins/canbus/qtvirtualcanbusd.dll').open('rb').read()) + assert m.digest() == binascii.unhexlify('98985de41ddba789d039bb10d86ea3015bf0d8d9fa86b25a0490044c247233d3') + else: + _dict = archive.extractall(return_dict=return_dict) + m = hashlib.sha256() + m.update(_dict['5.13.0/mingw73_64/plugins/canbus/qtvirtualcanbusd.dll'].read()) + assert m.digest() == binascii.unhexlify('98985de41ddba789d039bb10d86ea3015bf0d8d9fa86b25a0490044c247233d3') archive.close() - m = hashlib.sha256() - m.update(tmp_path.joinpath('5.13.0/mingw73_64/plugins/canbus/qtvirtualcanbusd.dll').open('rb').read()) - assert m.digest() == binascii.unhexlify('98985de41ddba789d039bb10d86ea3015bf0d8d9fa86b25a0490044c247233d3') @pytest.mark.files -def test_copy(tmp_path): +@pytest.mark.parametrize('return_dict', [False, True]) +def test_copy(tmp_path, return_dict: bool): """ test loading of copy compressed files.(help wanted)""" - check_archive(py7zr.SevenZipFile(open(os.path.join(testdata_path, 'copy.7z'), 'rb')), tmp_path) + check_archive(py7zr.SevenZipFile(open(os.path.join(testdata_path, 'copy.7z'), 'rb')), tmp_path, return_dict) @pytest.mark.files -def test_close_unlink(tmp_path): +@pytest.mark.parametrize('return_dict', [False, True]) +def test_close_unlink(tmp_path, return_dict: bool): shutil.copyfile(os.path.join(testdata_path, 'test_1.7z'), str(tmp_path.joinpath('test_1.7z'))) archive = py7zr.SevenZipFile(tmp_path.joinpath('test_1.7z')) - archive.extractall(path=tmp_path) + if not return_dict: + archive.extractall(path=tmp_path, return_dict=return_dict) + else: + _dict = archive.extractall(return_dict=return_dict) archive.close() tmp_path.joinpath('test_1.7z').unlink() @@ -266,16 +346,24 @@ def test_asyncio_executor(tmp_path): @pytest.mark.files -def test_no_main_streams(tmp_path): +@pytest.mark.parametrize('return_dict', [False, True]) +def test_no_main_streams(tmp_path, return_dict: bool): archive = py7zr.SevenZipFile(open(os.path.join(testdata_path, 'test_folder.7z'), 'rb')) - archive.extractall(path=tmp_path) + if not return_dict: + archive.extractall(path=tmp_path, return_dict=return_dict) + else: + _dict = archive.extractall(return_dict=return_dict) archive.close() @pytest.mark.files -def test_extract_encrypted_1(tmp_path): +@pytest.mark.parametrize('return_dict', [False, True]) +def test_extract_encrypted_1(tmp_path, return_dict: bool): archive = py7zr.SevenZipFile(open(os.path.join(testdata_path, 'encrypted_1.7z'), 'rb'), password='secret') - archive.extractall(path=tmp_path) + if not return_dict: + archive.extractall(path=tmp_path, return_dict=return_dict) + else: + _dict = archive.extractall(return_dict=return_dict) archive.close() @@ -283,38 +371,58 @@ def test_extract_encrypted_1(tmp_path): @pytest.mark.timeout(30) @pytest.mark.skipif(sys.platform.startswith("win") and (ctypes.windll.shell32.IsUserAnAdmin() == 0), reason="Administrator rights is required to make symlink on windows") -def test_extract_encrypted_2(tmp_path): +@pytest.mark.parametrize('return_dict', [False, True]) +def test_extract_encrypted_2(tmp_path, return_dict: bool): archive = py7zr.SevenZipFile(open(os.path.join(testdata_path, 'encrypted_2.7z'), 'rb'), password='secret') - archive.extractall(path=tmp_path) + if not return_dict: + archive.extractall(path=tmp_path, return_dict=return_dict) + else: + _dict = archive.extractall(return_dict=return_dict) archive.close() @pytest.mark.files -def test_extract_bzip2(tmp_path): +@pytest.mark.parametrize('return_dict', [False, True]) +def test_extract_bzip2(tmp_path, return_dict: bool): archive = py7zr.SevenZipFile(open(os.path.join(testdata_path, 'bzip2.7z'), 'rb')) - archive.extractall(path=tmp_path) + if not return_dict: + archive.extractall(path=tmp_path, return_dict=return_dict) + else: + _dict = archive.extractall(return_dict=return_dict) archive.close() @pytest.mark.files -def test_extract_bzip2_2(tmp_path): +@pytest.mark.parametrize('return_dict', [False, True]) +def test_extract_bzip2_2(tmp_path, return_dict: bool): archive = py7zr.SevenZipFile(open(os.path.join(testdata_path, 'bzip2_2.7z'), 'rb')) - archive.extractall(path=tmp_path) + if not return_dict: + archive.extractall(path=tmp_path, return_dict=return_dict) + else: + _dict = archive.extractall(return_dict=return_dict) archive.close() @pytest.mark.files -def test_extract_ppmd(tmp_path): +@pytest.mark.parametrize('return_dict', [False, True]) +def test_extract_ppmd(tmp_path, return_dict: bool): with pytest.raises(UnsupportedCompressionMethodError): archive = py7zr.SevenZipFile(open(os.path.join(testdata_path, 'ppmd.7z'), 'rb')) - archive.extractall(path=tmp_path) + if not return_dict: + archive.extractall(path=tmp_path, return_dict=return_dict) + else: + _dict = archive.extractall(return_dict=return_dict) archive.close() @pytest.mark.files -def test_extract_deflate(tmp_path): +@pytest.mark.parametrize('return_dict', [False, True]) +def test_extract_deflate(tmp_path, return_dict: bool): with py7zr.SevenZipFile(open(os.path.join(testdata_path, 'deflate.7z'), 'rb')) as archive: - archive.extractall(path=tmp_path) + if not return_dict: + archive.extractall(path=tmp_path, return_dict=return_dict) + else: + _dict = archive.extractall(return_dict=return_dict) @pytest.mark.files @@ -332,7 +440,11 @@ def test_extract_symlink_with_relative_target_path(tmp_path): @pytest.mark.files @pytest.mark.skipif(sys.platform.startswith("win") and (ctypes.windll.shell32.IsUserAnAdmin() == 0), reason="Administrator rights is required to make symlink on windows") -def test_extract_emptystream_mix(tmp_path): +@pytest.mark.parametrize('return_dict', [False, True]) +def test_extract_emptystream_mix(tmp_path, return_dict: bool): archive = py7zr.SevenZipFile(os.path.join(testdata_path, 'test_6.7z'), 'r') - archive.extractall(path=tmp_path) + if not return_dict: + archive.extractall(path=tmp_path, return_dict=return_dict) + else: + _dict = archive.extractall(return_dict=return_dict) archive.close()