From 4d1b37a58de1cadd8c3fc3511cf024bab96af0cf Mon Sep 17 00:00:00 2001 From: Charles LeDoux Date: Wed, 27 Dec 2017 17:07:59 -0600 Subject: [PATCH 1/5] Call instead of raise pytest.raise() Why: * pytest.raise is not an exception. --- tests/__init__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/__init__.py b/tests/__init__.py index a806764..1f82ccd 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -34,7 +34,7 @@ def _need_func(testfunc, name, description): def check_func(func): def newfunc(*args, **kwargs): if not testfunc(name): - raise pytest.skip("%s %r is not available" % (description, name)) + pytest.skip("%s %r is not available" % (description, name)) return func(*args, **kwargs) setattr(newfunc, fnameattr, getattr(func, fnameattr)) return newfunc @@ -72,9 +72,9 @@ def needs_codec (program, codec): def check_prog (f): def newfunc (*args, **kwargs): if not patoolib.util.find_program(program): - raise pytest.skip("program `%s' not available" % program) + pytest.skip("program `%s' not available" % program) if not has_codec(program, codec): - raise pytest.skip("codec `%s' for program `%s' not available" % (codec, program)) + pytest.skip("codec `%s' for program `%s' not available" % (codec, program)) return f(*args, **kwargs) setattr(newfunc, fnameattr, getattr(f, fnameattr)) return newfunc @@ -95,7 +95,7 @@ def skip_on_travis(): def check_func(func): def newfunc(*args, **kwargs): if "TRAVIS" in os.environ: - raise pytest.skip("Skip on TRAVIS CI build.") + pytest.skip("Skip on TRAVIS CI build.") return func(*args, **kwargs) setattr(newfunc, fnameattr, getattr(func, fnameattr)) return newfunc From cadeb1ca9f05a1cc1ecfacab73c0b13770cebc81 Mon Sep 17 00:00:00 2001 From: Charles LeDoux Date: Wed, 27 Dec 2017 17:08:26 -0600 Subject: [PATCH 2/5] Fix require_one_program to actually require only one Why: * Currently uses an any which means *all* programs will be required. This change addresses the need by: * Switchs the *all* to an *any* so that at least one is required --- tests/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/__init__.py b/tests/__init__.py index 1f82ccd..7c35d5f 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -53,7 +53,7 @@ def needs_program(name): def needs_one_program(programs): """Decorator skipping test if not one of given programs are available.""" - return _need_func(lambda x: all(map(patoolib.util.find_program, x)), programs, 'programs') + return _need_func(lambda x: any(map(patoolib.util.find_program, x)), programs, 'programs') def needs_module(name): From 03018b4e5b1e8b1c5b76feec34b0e02edfdd8181 Mon Sep 17 00:00:00 2001 From: Charles LeDoux Date: Wed, 27 Dec 2017 18:15:20 -0600 Subject: [PATCH 3/5] Only return separate encoding if `program_supports_compression` Why: * To prevent archives such as archive.rar.gz from breaking patool. This change addresses the need by: * move program_supports_compression above the `import util` line * If we don't do this, we have a circular import. * Import program_supports_compression into util. * Only return separate mime and encoding if program_support_compression returns True. * Otherwise return the mime of the encoding and no encoding. * Add fixes so that current tests still pass. * In program_support_compression: - Test tar separately and check all supported tar wrappers. * In test_tar: - Add file requirement for compress in the compress check. - Otherwise tar tries and failes when compress isn't installed. --- patoolib/__init__.py | 24 +++++++++++++----------- patoolib/util.py | 9 +++++++-- tests/archives/test_tar.py | 1 + tests/test_mime.py | 1 + 4 files changed, 22 insertions(+), 13 deletions(-) diff --git a/patoolib/__init__.py b/patoolib/__init__.py index f50d887..25ee4b4 100644 --- a/patoolib/__init__.py +++ b/patoolib/__init__.py @@ -25,7 +25,7 @@ import importlib from .configuration import App, Version as __version__ __all__ = ['list_formats', 'list_archive', 'extract_archive', 'test_archive', 'create_archive', 'diff_archives', 'search_archive', 'repack_archive', - 'recompress_archive'] + 'recompress_archive', 'program_supports_compression'] # Supported archive commands @@ -284,6 +284,18 @@ ProgramModules = { } +def program_supports_compression (program, compression): + """Decide if the given program supports the compression natively. + @return: True iff the program supports the given compression format + natively, else False. + """ + if program in ('tar', ): + return compression in ('gzip', 'bzip2', 'xz', 'lzip', 'compress', 'lzma') + py_lzma + elif program in ('star', 'bsdtar', 'py_tarfile'): + return compression in ('gzip', 'bzip2') + py_lzma + return False + + from . import util def get_archive_format (filename): @@ -336,16 +348,6 @@ def find_archive_program (format, command, program=None): raise util.PatoolError("could not find an executable program to %s format %s; candidates are (%s)," % (command, format, ",".join(programs))) -def program_supports_compression (program, compression): - """Decide if the given program supports the compression natively. - @return: True iff the program supports the given compression format - natively, else False. - """ - if program in ('tar', 'star', 'bsdtar', 'py_tarfile'): - return compression in ('gzip', 'bzip2') + py_lzma - return False - - def list_formats (): """Print information about available archive formats to stdout.""" print("Archive programs of", App) diff --git a/patoolib/util.py b/patoolib/util.py index 5975e75..e0976bd 100644 --- a/patoolib/util.py +++ b/patoolib/util.py @@ -24,7 +24,7 @@ import tempfile import time import traceback import locale -from . import configuration, ArchiveMimetypes, ArchiveCompressions +from . import configuration, ArchiveMimetypes, ArchiveCompressions, program_supports_compression try: from shutil import which except ImportError: @@ -314,7 +314,12 @@ def guess_mime_file (filename): elif mime2 in ArchiveMimetypes: mime = mime2 encoding = get_file_mime_encoding(outparts) - return mime, encoding + # Only return mime and encoding if the given mime can natively support the encoding. + if program_supports_compression(ArchiveMimetypes.get(mime), encoding): + return mime, encoding + else: + # If encoding is None, default back to `mime`. + return Encoding2Mime.get(encoding, mime), None def guess_mime_file_mime (file_prog, filename): diff --git a/tests/archives/test_tar.py b/tests/archives/test_tar.py index 9de8d4b..7f31730 100644 --- a/tests/archives/test_tar.py +++ b/tests/archives/test_tar.py @@ -69,6 +69,7 @@ class TestTar (ArchiveTest): self.archive_commands('t.tgz.foo', skip_create=True) @needs_program('file') + @needs_program('compress') @needs_codec(program, 'compress') def test_tar_z_file (self): self.archive_commands('t.tar.Z.foo', skip_create=True) diff --git a/tests/test_mime.py b/tests/test_mime.py index c36d2d0..8b93ce0 100644 --- a/tests/test_mime.py +++ b/tests/test_mime.py @@ -138,6 +138,7 @@ class TestMime (unittest.TestCase): self.mime_test_file("t.zpaq", "application/zpaq") self.mime_test_file("t.zpaq.foo", "application/zpaq") + @needs_program('file') @needs_program('lzip') def test_mime_file_lzip (self): From eadc1561707efcdecd44ca1c203e7cbb63b4d680 Mon Sep 17 00:00:00 2001 From: Charles LeDoux Date: Wed, 27 Dec 2017 18:20:46 -0600 Subject: [PATCH 4/5] Add tests for nested compression Why: * To ensure we don't try and unrar a rar.gz file. This change addresses the need by: * Adds test file archive.rar.gz * Add mime check to ensure we get the mime of gzip, not rar. --- tests/data/t.rar.gz | Bin 0 -> 119 bytes tests/data/t.rar.gz.foo | Bin 0 -> 119 bytes tests/test_mime.py | 6 ++++++ 3 files changed, 6 insertions(+) create mode 100644 tests/data/t.rar.gz create mode 100644 tests/data/t.rar.gz.foo diff --git a/tests/data/t.rar.gz b/tests/data/t.rar.gz new file mode 100644 index 0000000000000000000000000000000000000000..ccde84c6d32876a93a138377541a6d10113a8e69 GIT binary patch literal 119 zcmV--0Eqt|iwFpiCPZ2Q19UEOVR8TqN-R>8VrMu%p_qYzmjMEDo|h;zs55W_nM^>; z+_6E$NY*acM%I{}VL>AULrF}DUP(oXAorIe^WN8+&HomaEMM}VL6HFlm_dXMP=|;C ZBf|?vppGN9)eH{o3;;zM3aV}Z004HtEl&Ud literal 0 HcmV?d00001 diff --git a/tests/data/t.rar.gz.foo b/tests/data/t.rar.gz.foo new file mode 100644 index 0000000000000000000000000000000000000000..ccde84c6d32876a93a138377541a6d10113a8e69 GIT binary patch literal 119 zcmV--0Eqt|iwFpiCPZ2Q19UEOVR8TqN-R>8VrMu%p_qYzmjMEDo|h;zs55W_nM^>; z+_6E$NY*acM%I{}VL>AULrF}DUP(oXAorIe^WN8+&HomaEMM}VL6HFlm_dXMP=|;C ZBf|?vppGN9)eH{o3;;zM3aV}Z004HtEl&Ud literal 0 HcmV?d00001 diff --git a/tests/test_mime.py b/tests/test_mime.py index 8b93ce0..a23c81e 100644 --- a/tests/test_mime.py +++ b/tests/test_mime.py @@ -150,6 +150,12 @@ class TestMime (unittest.TestCase): self.mime_test_file("t.tar.bz2.foo", "application/x-tar", "bzip2") self.mime_test_file("t.tbz2.foo", "application/x-tar", "bzip2") + @needs_program('file') + def test_nested_gzip (self): + # Ensure that a file that doesn't natively support encoding does not see the encoding + self.mime_test_file("t.rar.gz", "application/gzip") + self.mime_test_file("t.rar.gz.foo", "application/gzip") + @needs_program('file') @needs_program('gzip') def test_mime_file_gzip (self): From 403fe0706355cf321f99e46159bdfc6d286aa945 Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Tue, 11 Sep 2018 09:27:12 -0400 Subject: [PATCH 5/5] BF: orange is no longer available from APT (last seen in wheezy) --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 6a6f447..313a48e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,12 +11,13 @@ branches: # install some archive programs before_install: - sudo apt-get update -qq - - sudo apt-get install -qq archmage arj bzip2 lbzip2 pbzip2 cabextract ncompress cpio bsdcpio lzop lcab p7zip p7zip-full zip unzip rpm2cpio binutils arc nomarch unalz lrzip bsdtar rzip zoo xdms orange lzip plzip clzip pdlzip sharutils flac unadf zoo zpaq libchm-bin genisoimage rpm + - sudo apt-get install -qq archmage arj bzip2 lbzip2 pbzip2 cabextract ncompress cpio bsdcpio lzop lcab p7zip p7zip-full zip unzip rpm2cpio binutils arc nomarch unalz lrzip bsdtar rzip zoo xdms lzip plzip clzip pdlzip sharutils flac unadf zoo zpaq libchm-bin genisoimage rpm # apt errors: #E: Package 'p7zip-rar' has no installation candidate #E: Package 'rar' has no installation candidate #E: Package 'unrar' has no installation candidate #E: Package 'lha' has no installation candidate +#E: Package 'orange' has no installation candidate #E: Unable to locate package unace-nonfree #E: Unable to locate package zopfli