From a3ec3ad9e20e7d9ed148d4cfbd22aebec608b42a Mon Sep 17 00:00:00 2001 From: Hai Shi Date: Tue, 19 May 2020 06:02:57 +0800 Subject: [PATCH] bpo-40275: More lazy imports in test.support (GH-20131) Make the the following imports lazy in test.support: * bz2 * gzip * lzma * resource * zlib The following test.support decorators now need to be called with parenthesis: * @support.requires_bz2 * @support.requires_gzip * @support.requires_lzma * @support.requires_zlib For example, "@requires_zlib" becomes "@requires_zlib()". --- Lib/test/support/__init__.py | 74 +++++++++++++++-------------- Lib/test/test_importlib/test_zip.py | 4 +- Lib/test/test_logging.py | 2 +- Lib/test/test_shutil.py | 24 +++++----- Lib/test/test_tarfile.py | 6 +-- Lib/test/test_venv.py | 2 +- Lib/test/test_zipapp.py | 2 +- Lib/test/test_zipfile.py | 40 ++++++++-------- Lib/test/test_zipfile64.py | 2 +- Lib/test/test_zipimport.py | 2 +- 10 files changed, 81 insertions(+), 77 deletions(-) diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index a9f9908c7fa..8dee5b9dcc7 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -28,31 +28,6 @@ import warnings from .testresult import get_test_runner -try: - import zlib -except ImportError: - zlib = None - -try: - import gzip -except ImportError: - gzip = None - -try: - import bz2 -except ImportError: - bz2 = None - -try: - import lzma -except ImportError: - lzma = None - -try: - import resource -except ImportError: - resource = None - __all__ = [ # globals "PIPE_MAX_SIZE", "verbose", "max_memuse", "use_resources", "failfast", @@ -705,13 +680,33 @@ requires_IEEE_754 = unittest.skipUnless( float.__getformat__("double").startswith("IEEE"), "test requires IEEE 754 doubles") -requires_zlib = unittest.skipUnless(zlib, 'requires zlib') +def requires_zlib(reason='requires zlib'): + try: + import zlib + except ImportError: + zlib = None + return unittest.skipUnless(zlib, reason) -requires_gzip = unittest.skipUnless(gzip, 'requires gzip') +def requires_gzip(reason='requires gzip'): + try: + import gzip + except ImportError: + gzip = None + return unittest.skipUnless(gzip, reason) -requires_bz2 = unittest.skipUnless(bz2, 'requires bz2') +def requires_bz2(reason='requires bz2'): + try: + import bz2 + except ImportError: + bz2 = None + return unittest.skipUnless(bz2, reason) -requires_lzma = unittest.skipUnless(lzma, 'requires lzma') +def requires_lzma(reason='requires lzma'): + try: + import lzma + except ImportError: + lzma = None + return unittest.skipUnless(lzma, reason) is_jython = sys.platform.startswith('java') @@ -1062,6 +1057,10 @@ def check_syntax_warning(testcase, statement, errtext='', *, lineno=1, offset=No def open_urlresource(url, *args, **kw): import urllib.request, urllib.parse + try: + import gzip + except ImportError: + gzip = None check = kw.pop('check', None) @@ -2579,11 +2578,16 @@ class SuppressCrashReport: self.old_modes[report_type] = old_mode, old_file else: - if resource is not None: + try: + import resource + self.resource = resource + except ImportError: + self.resource = None + if self.resource is not None: try: - self.old_value = resource.getrlimit(resource.RLIMIT_CORE) - resource.setrlimit(resource.RLIMIT_CORE, - (0, self.old_value[1])) + self.old_value = self.resource.getrlimit(self.resource.RLIMIT_CORE) + self.resource.setrlimit(self.resource.RLIMIT_CORE, + (0, self.old_value[1])) except (ValueError, OSError): pass @@ -2621,9 +2625,9 @@ class SuppressCrashReport: msvcrt.CrtSetReportMode(report_type, old_mode) msvcrt.CrtSetReportFile(report_type, old_file) else: - if resource is not None: + if self.resource is not None: try: - resource.setrlimit(resource.RLIMIT_CORE, self.old_value) + self.resource.setrlimit(self.resource.RLIMIT_CORE, self.old_value) except (ValueError, OSError): pass diff --git a/Lib/test/test_importlib/test_zip.py b/Lib/test/test_importlib/test_zip.py index 9466ca4a5f4..fa87cd7cb10 100644 --- a/Lib/test/test_importlib/test_zip.py +++ b/Lib/test/test_importlib/test_zip.py @@ -10,7 +10,7 @@ from importlib.resources import path from test.support import requires_zlib -@requires_zlib +@requires_zlib() class TestZip(unittest.TestCase): root = 'test.test_importlib.data' @@ -50,7 +50,7 @@ class TestZip(unittest.TestCase): assert '.whl/' in path, path -@requires_zlib +@requires_zlib() class TestEgg(TestZip): def setUp(self): # Find the path to the example-*.egg so we can add it to the front of diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index 4cc45f71071..9a114451913 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -5076,7 +5076,7 @@ class RotatingFileHandlerTest(BaseFileTest): self.assertFalse(os.path.exists(rh.namer(self.fn + ".1"))) rh.close() - @support.requires_zlib + @support.requires_zlib() def test_rotator(self): def namer(name): return name + ".gz" diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py index b9fdfd1350a..e56b337083c 100644 --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -1246,7 +1246,7 @@ class TestArchives(BaseTest, unittest.TestCase): ### shutil.make_archive - @support.requires_zlib + @support.requires_zlib() def test_make_tarball(self): # creating something to tar root_dir, base_dir = self._create_files('') @@ -1302,7 +1302,7 @@ class TestArchives(BaseTest, unittest.TestCase): write_file((root_dir, 'outer'), 'xxx') return root_dir, base_dir - @support.requires_zlib + @support.requires_zlib() @unittest.skipUnless(shutil.which('tar'), 'Need the tar command to run') def test_tarfile_vs_tar(self): @@ -1335,7 +1335,7 @@ class TestArchives(BaseTest, unittest.TestCase): self.assertEqual(tarball, base_name + '.tar') self.assertTrue(os.path.isfile(tarball)) - @support.requires_zlib + @support.requires_zlib() def test_make_zipfile(self): # creating something to zip root_dir, base_dir = self._create_files() @@ -1372,7 +1372,7 @@ class TestArchives(BaseTest, unittest.TestCase): ['dist/', 'dist/sub/', 'dist/sub2/', 'dist/file1', 'dist/file2', 'dist/sub/file3']) - @support.requires_zlib + @support.requires_zlib() @unittest.skipUnless(shutil.which('zip'), 'Need the zip command to run') def test_zipfile_vs_zip(self): @@ -1398,7 +1398,7 @@ class TestArchives(BaseTest, unittest.TestCase): names2 = zf.namelist() self.assertEqual(sorted(names), sorted(names2)) - @support.requires_zlib + @support.requires_zlib() @unittest.skipUnless(shutil.which('unzip'), 'Need the unzip command to run') def test_unzip_zipfile(self): @@ -1427,7 +1427,7 @@ class TestArchives(BaseTest, unittest.TestCase): base_name = os.path.join(tmpdir, 'archive') self.assertRaises(ValueError, make_archive, base_name, 'xxx') - @support.requires_zlib + @support.requires_zlib() def test_make_archive_owner_group(self): # testing make_archive with owner and group, with various combinations # this works even if there's not gid/uid support @@ -1455,7 +1455,7 @@ class TestArchives(BaseTest, unittest.TestCase): self.assertTrue(os.path.isfile(res)) - @support.requires_zlib + @support.requires_zlib() @unittest.skipUnless(UID_GID_SUPPORT, "Requires grp and pwd support") def test_tarfile_root_owner(self): root_dir, base_dir = self._create_files() @@ -1500,7 +1500,7 @@ class TestArchives(BaseTest, unittest.TestCase): self.assertEqual(make_archive('test', 'tar'), 'test.tar') self.assertTrue(os.path.isfile('test.tar')) - @support.requires_zlib + @support.requires_zlib() def test_make_zipfile_in_curdir(self): # Issue #21280 root_dir = self.mkdtemp() @@ -1555,20 +1555,20 @@ class TestArchives(BaseTest, unittest.TestCase): def test_unpack_archive_tar(self): self.check_unpack_archive('tar') - @support.requires_zlib + @support.requires_zlib() def test_unpack_archive_gztar(self): self.check_unpack_archive('gztar') - @support.requires_bz2 + @support.requires_bz2() def test_unpack_archive_bztar(self): self.check_unpack_archive('bztar') - @support.requires_lzma + @support.requires_lzma() @unittest.skipIf(AIX and not _maxdataOK(), "AIX MAXDATA must be 0x20000000 or larger") def test_unpack_archive_xztar(self): self.check_unpack_archive('xztar') - @support.requires_zlib + @support.requires_zlib() def test_unpack_archive_zip(self): self.check_unpack_archive('zip') diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py index 25e9e936044..be66f1f89e6 100644 --- a/Lib/test/test_tarfile.py +++ b/Lib/test/test_tarfile.py @@ -57,21 +57,21 @@ class TarTest: def mode(self): return self.prefix + self.suffix -@support.requires_gzip +@support.requires_gzip() class GzipTest: tarname = gzipname suffix = 'gz' open = gzip.GzipFile if gzip else None taropen = tarfile.TarFile.gzopen -@support.requires_bz2 +@support.requires_bz2() class Bz2Test: tarname = bz2name suffix = 'bz2' open = bz2.BZ2File if bz2 else None taropen = tarfile.TarFile.bz2open -@support.requires_lzma +@support.requires_lzma() class LzmaTest: tarname = xzname suffix = 'xz' diff --git a/Lib/test/test_venv.py b/Lib/test/test_venv.py index b2794cd992a..44c62193bf7 100644 --- a/Lib/test/test_venv.py +++ b/Lib/test/test_venv.py @@ -530,7 +530,7 @@ class EnsurePipTest(BaseTest): # Issue #26610: pip/pep425tags.py requires ctypes @unittest.skipUnless(ctypes, 'pip requires ctypes') - @requires_zlib + @requires_zlib() def test_with_pip(self): self.do_test_with_pip(False) self.do_test_with_pip(True) diff --git a/Lib/test/test_zipapp.py b/Lib/test/test_zipapp.py index 73bddc79c17..69f2e55d563 100644 --- a/Lib/test/test_zipapp.py +++ b/Lib/test/test_zipapp.py @@ -101,7 +101,7 @@ class ZipAppTest(unittest.TestCase): expected_target = self.tmpdir / 'source.pyz' self.assertTrue(expected_target.is_file()) - @requires_zlib + @requires_zlib() def test_create_archive_with_compression(self): # Test packing a directory into a compressed archive. source = self.tmpdir / 'source' diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py index 29d98c8092d..c9ca1ddaafe 100644 --- a/Lib/test/test_zipfile.py +++ b/Lib/test/test_zipfile.py @@ -640,7 +640,7 @@ class StoredTestsWithSourceFile(AbstractTestsWithSourceFile, self.assertEqual(zinfo.date_time, (2107, 12, 31, 23, 59, 59)) -@requires_zlib +@requires_zlib() class DeflateTestsWithSourceFile(AbstractTestsWithSourceFile, unittest.TestCase): compression = zipfile.ZIP_DEFLATED @@ -656,12 +656,12 @@ class DeflateTestsWithSourceFile(AbstractTestsWithSourceFile, self.assertEqual(sinfo.compress_type, zipfile.ZIP_STORED) self.assertEqual(dinfo.compress_type, zipfile.ZIP_DEFLATED) -@requires_bz2 +@requires_bz2() class Bzip2TestsWithSourceFile(AbstractTestsWithSourceFile, unittest.TestCase): compression = zipfile.ZIP_BZIP2 -@requires_lzma +@requires_lzma() class LzmaTestsWithSourceFile(AbstractTestsWithSourceFile, unittest.TestCase): compression = zipfile.ZIP_LZMA @@ -1075,17 +1075,17 @@ class StoredTestZip64InSmallFiles(AbstractTestZip64InSmallFiles, self.assertEqual(zf.read(zinfo), expected_content) -@requires_zlib +@requires_zlib() class DeflateTestZip64InSmallFiles(AbstractTestZip64InSmallFiles, unittest.TestCase): compression = zipfile.ZIP_DEFLATED -@requires_bz2 +@requires_bz2() class Bzip2TestZip64InSmallFiles(AbstractTestZip64InSmallFiles, unittest.TestCase): compression = zipfile.ZIP_BZIP2 -@requires_lzma +@requires_lzma() class LzmaTestZip64InSmallFiles(AbstractTestZip64InSmallFiles, unittest.TestCase): compression = zipfile.ZIP_LZMA @@ -1120,15 +1120,15 @@ class AbstractWriterTests: class StoredWriterTests(AbstractWriterTests, unittest.TestCase): compression = zipfile.ZIP_STORED -@requires_zlib +@requires_zlib() class DeflateWriterTests(AbstractWriterTests, unittest.TestCase): compression = zipfile.ZIP_DEFLATED -@requires_bz2 +@requires_bz2() class Bzip2WriterTests(AbstractWriterTests, unittest.TestCase): compression = zipfile.ZIP_BZIP2 -@requires_lzma +@requires_lzma() class LzmaWriterTests(AbstractWriterTests, unittest.TestCase): compression = zipfile.ZIP_LZMA @@ -1582,7 +1582,7 @@ class OtherTests(unittest.TestCase): self.assertRaises(NotImplementedError, zipfile.ZipFile, io.BytesIO(data), 'r') - @requires_zlib + @requires_zlib() def test_read_unicode_filenames(self): # bug #10801 fname = findfile('zip_cp437_header.zip') @@ -2018,7 +2018,7 @@ class OtherTests(unittest.TestCase): fp.seek(0, os.SEEK_SET) self.assertEqual(fp.tell(), 0) - @requires_bz2 + @requires_bz2() def test_decompress_without_3rd_party_library(self): data = b'PK\x05\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' zip_file = io.BytesIO(data) @@ -2076,7 +2076,7 @@ class StoredBadCrcTests(AbstractBadCrcTests, unittest.TestCase): b'lePK\005\006\0\0\0\0\001\0\001\0003\000' b'\0\0/\0\0\0\0\0') -@requires_zlib +@requires_zlib() class DeflateBadCrcTests(AbstractBadCrcTests, unittest.TestCase): compression = zipfile.ZIP_DEFLATED zip_with_bad_crc = ( @@ -2089,7 +2089,7 @@ class DeflateBadCrcTests(AbstractBadCrcTests, unittest.TestCase): b'\x00afilePK\x05\x06\x00\x00\x00\x00\x01\x00' b'\x01\x003\x00\x00\x003\x00\x00\x00\x00\x00') -@requires_bz2 +@requires_bz2() class Bzip2BadCrcTests(AbstractBadCrcTests, unittest.TestCase): compression = zipfile.ZIP_BZIP2 zip_with_bad_crc = ( @@ -2105,7 +2105,7 @@ class Bzip2BadCrcTests(AbstractBadCrcTests, unittest.TestCase): b'\x05\x06\x00\x00\x00\x00\x01\x00\x01\x003\x00\x00\x00[\x00' b'\x00\x00\x00\x00') -@requires_lzma +@requires_lzma() class LzmaBadCrcTests(AbstractBadCrcTests, unittest.TestCase): compression = zipfile.ZIP_LZMA zip_with_bad_crc = ( @@ -2172,7 +2172,7 @@ class DecryptionTests(unittest.TestCase): self.zip2.setpassword(b"perl") self.assertRaises(RuntimeError, self.zip2.read, "zero") - @requires_zlib + @requires_zlib() def test_good_password(self): self.zip.setpassword(b"python") self.assertEqual(self.zip.read("test.txt"), self.plain) @@ -2318,17 +2318,17 @@ class StoredTestsWithRandomBinaryFiles(AbstractTestsWithRandomBinaryFiles, unittest.TestCase): compression = zipfile.ZIP_STORED -@requires_zlib +@requires_zlib() class DeflateTestsWithRandomBinaryFiles(AbstractTestsWithRandomBinaryFiles, unittest.TestCase): compression = zipfile.ZIP_DEFLATED -@requires_bz2 +@requires_bz2() class Bzip2TestsWithRandomBinaryFiles(AbstractTestsWithRandomBinaryFiles, unittest.TestCase): compression = zipfile.ZIP_BZIP2 -@requires_lzma +@requires_lzma() class LzmaTestsWithRandomBinaryFiles(AbstractTestsWithRandomBinaryFiles, unittest.TestCase): compression = zipfile.ZIP_LZMA @@ -2416,7 +2416,7 @@ class UnseekableTests(unittest.TestCase): self.assertEqual(zipf.read('twos'), b'222') -@requires_zlib +@requires_zlib() class TestsWithMultipleOpens(unittest.TestCase): @classmethod def setUpClass(cls): @@ -2682,7 +2682,7 @@ class CommandLineTest(unittest.TestCase): PYTHONIOENCODING='ascii:backslashreplace') self.assertEqual(out, expected) - @requires_zlib + @requires_zlib() def test_create_command(self): self.addCleanup(unlink, TESTFN) with open(TESTFN, 'w') as f: diff --git a/Lib/test/test_zipfile64.py b/Lib/test/test_zipfile64.py index 56746bc08f6..3a788de2212 100644 --- a/Lib/test/test_zipfile64.py +++ b/Lib/test/test_zipfile64.py @@ -73,7 +73,7 @@ class TestsWithSourceFile(unittest.TestCase): self.assertFalse(f.closed) self.zipTest(TESTFN2, zipfile.ZIP_STORED) - @requires_zlib + @requires_zlib() def testDeflated(self): # Try the temp file first. If we do TESTFN2 first, then it hogs # gigabytes of disk space for the duration of the test. diff --git a/Lib/test/test_zipimport.py b/Lib/test/test_zipimport.py index 2af8689c1d2..560286071c6 100644 --- a/Lib/test/test_zipimport.py +++ b/Lib/test/test_zipimport.py @@ -683,7 +683,7 @@ class UncompressedZipImportTestCase(ImportHooksBaseTestCase): self.doTest(".py", files, TESTMOD, comment=b"c" * ((1 << 16) - 1)) -@support.requires_zlib +@support.requires_zlib() class CompressedZipImportTestCase(UncompressedZipImportTestCase): compression = ZIP_DEFLATED