diff --git a/.codespell-ignorewords b/.codespell-ignorewords index 70878b38..9f2497a5 100644 --- a/.codespell-ignorewords +++ b/.codespell-ignorewords @@ -1,3 +1,4 @@ nd te fastr +inpt diff --git a/extras/fileformats/extras/application/archive.py b/extras/fileformats/extras/application/archive.py index e3c02146..08d1e133 100644 --- a/extras/fileformats/extras/application/archive.py +++ b/extras/fileformats/extras/application/archive.py @@ -146,7 +146,7 @@ def create_zip( in_file: FsObject, out_file: ty.Optional[Path] = None, base_dir: ty.Optional[Path] = None, - compression: int = zipfile.ZIP_DEFLATED, + compression: int | str = zipfile.ZIP_DEFLATED, allowZip64: bool = True, compresslevel: ty.Optional[int] = None, strict_timestamps: bool = True, @@ -157,6 +157,17 @@ def create_zip( "Can only archive file-sets with single paths currently" ) + if isinstance(compression, str): + try: + compression_flag: int = getattr(zipfile, compression.upper()) + except AttributeError: + raise ValueError( + f"Invalid compression type, {compression!r}, " + "choose from 'ZIP_STORED', 'ZIP_DEFLATED', 'ZIP_BZIP2', 'ZIP_LZMA'" + ) + else: + compression_flag = compression + if out_file is None: # type: ignore[comparison-overlap] out_file = Path(Path(in_file).name + ".zip") @@ -169,7 +180,7 @@ def create_zip( zipfile.ZipFile( out_file, mode="w", - compression=compression, + compression=compression_flag, allowZip64=allowZip64, compresslevel=compresslevel, strict_timestamps=strict_timestamps, diff --git a/extras/fileformats/extras/application/tests/test_application_archive.py b/extras/fileformats/extras/application/tests/test_application_archive.py index 4a576889..45f1ed68 100644 --- a/extras/fileformats/extras/application/tests/test_application_archive.py +++ b/extras/fileformats/extras/application/tests/test_application_archive.py @@ -39,6 +39,19 @@ def test_zip_roundtrip(archive_input): _roundtrip(archive_input, Zip) +@pytest.mark.parametrize( + "compression", ["ZIP_STORED", "ZIP_DEFLATED", "ZIP_BZIP2", "ZIP_LZMA"] +) +def test_zip_roundtrip_string_compression(archive_input, compression): + _roundtrip(archive_input, Zip, compression=compression) + + +def test_zip_string_compression_invalid(archive_input): + compressed_type = Directory if archive_input.is_dir() else PlainText + with pytest.raises(ValueError, match="Invalid compression type"): + Zip[compressed_type].convert(archive_input, compression="not-a-real-type") + + @pytest.mark.xfail(reason="Gzip converter is not implemented yet") def test_gzip_roundtrip(archive_input): _roundtrip(archive_input, Gzip) @@ -52,11 +65,11 @@ def test_tar_gz_roundtrip(archive_input): _roundtrip(archive_input, TarGzip) -def _roundtrip(input, archive_klass): - archive_klass.convert(input) # test generic archive +def _roundtrip(input, archive_klass, **kwargs): + archive_klass.convert(input, **kwargs) # test generic archive # Create classified archive that can be reversed compressed_type = Directory if input.is_dir() else PlainText - archive = archive_klass[compressed_type].convert(input) + archive = archive_klass[compressed_type].convert(input, **kwargs) assert isinstance(archive, archive_klass) output = compressed_type.convert(archive) if isinstance(input, File):