ยปCore Development>Code coverage>Lib/test/test_zipimport.py

Python code coverage for Lib/test/test_zipimport.py

#countcontent
1n/aimport sys
2n/aimport os
3n/aimport marshal
4n/aimport importlib
5n/aimport importlib.util
6n/aimport struct
7n/aimport time
8n/aimport unittest
9n/a
10n/afrom test import support
11n/a
12n/afrom zipfile import ZipFile, ZipInfo, ZIP_STORED, ZIP_DEFLATED
13n/a
14n/aimport zipimport
15n/aimport linecache
16n/aimport doctest
17n/aimport inspect
18n/aimport io
19n/afrom traceback import extract_tb, extract_stack, print_tb
20n/a
21n/atest_src = """\
22n/adef get_name():
23n/a return __name__
24n/adef get_file():
25n/a return __file__
26n/a"""
27n/atest_co = compile(test_src, "<???>", "exec")
28n/araise_src = 'def do_raise(): raise TypeError\n'
29n/a
30n/adef make_pyc(co, mtime, size):
31n/a data = marshal.dumps(co)
32n/a if type(mtime) is type(0.0):
33n/a # Mac mtimes need a bit of special casing
34n/a if mtime < 0x7fffffff:
35n/a mtime = int(mtime)
36n/a else:
37n/a mtime = int(-0x100000000 + int(mtime))
38n/a pyc = (importlib.util.MAGIC_NUMBER +
39n/a struct.pack("<ii", int(mtime), size & 0xFFFFFFFF) + data)
40n/a return pyc
41n/a
42n/adef module_path_to_dotted_name(path):
43n/a return path.replace(os.sep, '.')
44n/a
45n/aNOW = time.time()
46n/atest_pyc = make_pyc(test_co, NOW, len(test_src))
47n/a
48n/a
49n/aTESTMOD = "ziptestmodule"
50n/aTESTPACK = "ziptestpackage"
51n/aTESTPACK2 = "ziptestpackage2"
52n/aTEMP_DIR = os.path.abspath("junk95142")
53n/aTEMP_ZIP = os.path.abspath("junk95142.zip")
54n/a
55n/apyc_file = importlib.util.cache_from_source(TESTMOD + '.py')
56n/apyc_ext = '.pyc'
57n/a
58n/a
59n/aclass ImportHooksBaseTestCase(unittest.TestCase):
60n/a
61n/a def setUp(self):
62n/a self.path = sys.path[:]
63n/a self.meta_path = sys.meta_path[:]
64n/a self.path_hooks = sys.path_hooks[:]
65n/a sys.path_importer_cache.clear()
66n/a self.modules_before = support.modules_setup()
67n/a
68n/a def tearDown(self):
69n/a sys.path[:] = self.path
70n/a sys.meta_path[:] = self.meta_path
71n/a sys.path_hooks[:] = self.path_hooks
72n/a sys.path_importer_cache.clear()
73n/a support.modules_cleanup(*self.modules_before)
74n/a
75n/a
76n/aclass UncompressedZipImportTestCase(ImportHooksBaseTestCase):
77n/a
78n/a compression = ZIP_STORED
79n/a
80n/a def setUp(self):
81n/a # We're reusing the zip archive path, so we must clear the
82n/a # cached directory info and linecache.
83n/a linecache.clearcache()
84n/a zipimport._zip_directory_cache.clear()
85n/a ImportHooksBaseTestCase.setUp(self)
86n/a
87n/a def makeTree(self, files, dirName=TEMP_DIR):
88n/a # Create a filesystem based set of modules/packages
89n/a # defined by files under the directory dirName.
90n/a self.addCleanup(support.rmtree, dirName)
91n/a
92n/a for name, (mtime, data) in files.items():
93n/a path = os.path.join(dirName, name)
94n/a if path[-1] == os.sep:
95n/a if not os.path.isdir(path):
96n/a os.makedirs(path)
97n/a else:
98n/a dname = os.path.dirname(path)
99n/a if not os.path.isdir(dname):
100n/a os.makedirs(dname)
101n/a with open(path, 'wb') as fp:
102n/a fp.write(data)
103n/a
104n/a def makeZip(self, files, zipName=TEMP_ZIP, **kw):
105n/a # Create a zip archive based set of modules/packages
106n/a # defined by files in the zip file zipName. If the
107n/a # key 'stuff' exists in kw it is prepended to the archive.
108n/a self.addCleanup(support.unlink, zipName)
109n/a
110n/a with ZipFile(zipName, "w") as z:
111n/a for name, (mtime, data) in files.items():
112n/a zinfo = ZipInfo(name, time.localtime(mtime))
113n/a zinfo.compress_type = self.compression
114n/a z.writestr(zinfo, data)
115n/a
116n/a stuff = kw.get("stuff", None)
117n/a if stuff is not None:
118n/a # Prepend 'stuff' to the start of the zipfile
119n/a with open(zipName, "rb") as f:
120n/a data = f.read()
121n/a with open(zipName, "wb") as f:
122n/a f.write(stuff)
123n/a f.write(data)
124n/a
125n/a def doTest(self, expected_ext, files, *modules, **kw):
126n/a self.makeZip(files, **kw)
127n/a
128n/a sys.path.insert(0, TEMP_ZIP)
129n/a
130n/a mod = importlib.import_module(".".join(modules))
131n/a
132n/a call = kw.get('call')
133n/a if call is not None:
134n/a call(mod)
135n/a
136n/a if expected_ext:
137n/a file = mod.get_file()
138n/a self.assertEqual(file, os.path.join(TEMP_ZIP,
139n/a *modules) + expected_ext)
140n/a
141n/a def testAFakeZlib(self):
142n/a #
143n/a # This could cause a stack overflow before: importing zlib.py
144n/a # from a compressed archive would cause zlib to be imported
145n/a # which would find zlib.py in the archive, which would... etc.
146n/a #
147n/a # This test *must* be executed first: it must be the first one
148n/a # to trigger zipimport to import zlib (zipimport caches the
149n/a # zlib.decompress function object, after which the problem being
150n/a # tested here wouldn't be a problem anymore...
151n/a # (Hence the 'A' in the test method name: to make it the first
152n/a # item in a list sorted by name, like unittest.makeSuite() does.)
153n/a #
154n/a # This test fails on platforms on which the zlib module is
155n/a # statically linked, but the problem it tests for can't
156n/a # occur in that case (builtin modules are always found first),
157n/a # so we'll simply skip it then. Bug #765456.
158n/a #
159n/a if "zlib" in sys.builtin_module_names:
160n/a self.skipTest('zlib is a builtin module')
161n/a if "zlib" in sys.modules:
162n/a del sys.modules["zlib"]
163n/a files = {"zlib.py": (NOW, test_src)}
164n/a try:
165n/a self.doTest(".py", files, "zlib")
166n/a except ImportError:
167n/a if self.compression != ZIP_DEFLATED:
168n/a self.fail("expected test to not raise ImportError")
169n/a else:
170n/a if self.compression != ZIP_STORED:
171n/a self.fail("expected test to raise ImportError")
172n/a
173n/a def testPy(self):
174n/a files = {TESTMOD + ".py": (NOW, test_src)}
175n/a self.doTest(".py", files, TESTMOD)
176n/a
177n/a def testPyc(self):
178n/a files = {TESTMOD + pyc_ext: (NOW, test_pyc)}
179n/a self.doTest(pyc_ext, files, TESTMOD)
180n/a
181n/a def testBoth(self):
182n/a files = {TESTMOD + ".py": (NOW, test_src),
183n/a TESTMOD + pyc_ext: (NOW, test_pyc)}
184n/a self.doTest(pyc_ext, files, TESTMOD)
185n/a
186n/a def testEmptyPy(self):
187n/a files = {TESTMOD + ".py": (NOW, "")}
188n/a self.doTest(None, files, TESTMOD)
189n/a
190n/a def testBadMagic(self):
191n/a # make pyc magic word invalid, forcing loading from .py
192n/a badmagic_pyc = bytearray(test_pyc)
193n/a badmagic_pyc[0] ^= 0x04 # flip an arbitrary bit
194n/a files = {TESTMOD + ".py": (NOW, test_src),
195n/a TESTMOD + pyc_ext: (NOW, badmagic_pyc)}
196n/a self.doTest(".py", files, TESTMOD)
197n/a
198n/a def testBadMagic2(self):
199n/a # make pyc magic word invalid, causing an ImportError
200n/a badmagic_pyc = bytearray(test_pyc)
201n/a badmagic_pyc[0] ^= 0x04 # flip an arbitrary bit
202n/a files = {TESTMOD + pyc_ext: (NOW, badmagic_pyc)}
203n/a try:
204n/a self.doTest(".py", files, TESTMOD)
205n/a except ImportError:
206n/a pass
207n/a else:
208n/a self.fail("expected ImportError; import from bad pyc")
209n/a
210n/a def testBadMTime(self):
211n/a badtime_pyc = bytearray(test_pyc)
212n/a # flip the second bit -- not the first as that one isn't stored in the
213n/a # .py's mtime in the zip archive.
214n/a badtime_pyc[7] ^= 0x02
215n/a files = {TESTMOD + ".py": (NOW, test_src),
216n/a TESTMOD + pyc_ext: (NOW, badtime_pyc)}
217n/a self.doTest(".py", files, TESTMOD)
218n/a
219n/a def testPackage(self):
220n/a packdir = TESTPACK + os.sep
221n/a files = {packdir + "__init__" + pyc_ext: (NOW, test_pyc),
222n/a packdir + TESTMOD + pyc_ext: (NOW, test_pyc)}
223n/a self.doTest(pyc_ext, files, TESTPACK, TESTMOD)
224n/a
225n/a def testSubPackage(self):
226n/a # Test that subpackages function when loaded from zip
227n/a # archives.
228n/a packdir = TESTPACK + os.sep
229n/a packdir2 = packdir + TESTPACK2 + os.sep
230n/a files = {packdir + "__init__" + pyc_ext: (NOW, test_pyc),
231n/a packdir2 + "__init__" + pyc_ext: (NOW, test_pyc),
232n/a packdir2 + TESTMOD + pyc_ext: (NOW, test_pyc)}
233n/a self.doTest(pyc_ext, files, TESTPACK, TESTPACK2, TESTMOD)
234n/a
235n/a def testSubNamespacePackage(self):
236n/a # Test that implicit namespace subpackages function
237n/a # when loaded from zip archives.
238n/a packdir = TESTPACK + os.sep
239n/a packdir2 = packdir + TESTPACK2 + os.sep
240n/a # The first two files are just directory entries (so have no data).
241n/a files = {packdir: (NOW, ""),
242n/a packdir2: (NOW, ""),
243n/a packdir2 + TESTMOD + pyc_ext: (NOW, test_pyc)}
244n/a self.doTest(pyc_ext, files, TESTPACK, TESTPACK2, TESTMOD)
245n/a
246n/a def testMixedNamespacePackage(self):
247n/a # Test implicit namespace packages spread between a
248n/a # real filesystem and a zip archive.
249n/a packdir = TESTPACK + os.sep
250n/a packdir2 = packdir + TESTPACK2 + os.sep
251n/a packdir3 = packdir2 + TESTPACK + '3' + os.sep
252n/a files1 = {packdir: (NOW, ""),
253n/a packdir + TESTMOD + pyc_ext: (NOW, test_pyc),
254n/a packdir2: (NOW, ""),
255n/a packdir3: (NOW, ""),
256n/a packdir3 + TESTMOD + pyc_ext: (NOW, test_pyc),
257n/a packdir2 + TESTMOD + '3' + pyc_ext: (NOW, test_pyc),
258n/a packdir2 + TESTMOD + pyc_ext: (NOW, test_pyc)}
259n/a files2 = {packdir: (NOW, ""),
260n/a packdir + TESTMOD + '2' + pyc_ext: (NOW, test_pyc),
261n/a packdir2: (NOW, ""),
262n/a packdir2 + TESTMOD + '2' + pyc_ext: (NOW, test_pyc),
263n/a packdir2 + TESTMOD + pyc_ext: (NOW, test_pyc)}
264n/a
265n/a zip1 = os.path.abspath("path1.zip")
266n/a self.makeZip(files1, zip1)
267n/a
268n/a zip2 = TEMP_DIR
269n/a self.makeTree(files2, zip2)
270n/a
271n/a # zip2 should override zip1.
272n/a sys.path.insert(0, zip1)
273n/a sys.path.insert(0, zip2)
274n/a
275n/a mod = importlib.import_module(TESTPACK)
276n/a
277n/a # if TESTPACK is functioning as a namespace pkg then
278n/a # there should be two entries in the __path__.
279n/a # First should be path2 and second path1.
280n/a self.assertEqual(2, len(mod.__path__))
281n/a p1, p2 = mod.__path__
282n/a self.assertEqual(os.path.basename(TEMP_DIR), p1.split(os.sep)[-2])
283n/a self.assertEqual("path1.zip", p2.split(os.sep)[-2])
284n/a
285n/a # packdir3 should import as a namespace package.
286n/a # Its __path__ is an iterable of 1 element from zip1.
287n/a mod = importlib.import_module(packdir3.replace(os.sep, '.')[:-1])
288n/a self.assertEqual(1, len(mod.__path__))
289n/a mpath = list(mod.__path__)[0].split('path1.zip' + os.sep)[1]
290n/a self.assertEqual(packdir3[:-1], mpath)
291n/a
292n/a # TESTPACK/TESTMOD only exists in path1.
293n/a mod = importlib.import_module('.'.join((TESTPACK, TESTMOD)))
294n/a self.assertEqual("path1.zip", mod.__file__.split(os.sep)[-3])
295n/a
296n/a # And TESTPACK/(TESTMOD + '2') only exists in path2.
297n/a mod = importlib.import_module('.'.join((TESTPACK, TESTMOD + '2')))
298n/a self.assertEqual(os.path.basename(TEMP_DIR),
299n/a mod.__file__.split(os.sep)[-3])
300n/a
301n/a # One level deeper...
302n/a subpkg = '.'.join((TESTPACK, TESTPACK2))
303n/a mod = importlib.import_module(subpkg)
304n/a self.assertEqual(2, len(mod.__path__))
305n/a p1, p2 = mod.__path__
306n/a self.assertEqual(os.path.basename(TEMP_DIR), p1.split(os.sep)[-3])
307n/a self.assertEqual("path1.zip", p2.split(os.sep)[-3])
308n/a
309n/a # subpkg.TESTMOD exists in both zips should load from zip2.
310n/a mod = importlib.import_module('.'.join((subpkg, TESTMOD)))
311n/a self.assertEqual(os.path.basename(TEMP_DIR),
312n/a mod.__file__.split(os.sep)[-4])
313n/a
314n/a # subpkg.TESTMOD + '2' only exists in zip2.
315n/a mod = importlib.import_module('.'.join((subpkg, TESTMOD + '2')))
316n/a self.assertEqual(os.path.basename(TEMP_DIR),
317n/a mod.__file__.split(os.sep)[-4])
318n/a
319n/a # Finally subpkg.TESTMOD + '3' only exists in zip1.
320n/a mod = importlib.import_module('.'.join((subpkg, TESTMOD + '3')))
321n/a self.assertEqual('path1.zip', mod.__file__.split(os.sep)[-4])
322n/a
323n/a def testNamespacePackage(self):
324n/a # Test implicit namespace packages spread between multiple zip
325n/a # archives.
326n/a packdir = TESTPACK + os.sep
327n/a packdir2 = packdir + TESTPACK2 + os.sep
328n/a packdir3 = packdir2 + TESTPACK + '3' + os.sep
329n/a files1 = {packdir: (NOW, ""),
330n/a packdir + TESTMOD + pyc_ext: (NOW, test_pyc),
331n/a packdir2: (NOW, ""),
332n/a packdir3: (NOW, ""),
333n/a packdir3 + TESTMOD + pyc_ext: (NOW, test_pyc),
334n/a packdir2 + TESTMOD + '3' + pyc_ext: (NOW, test_pyc),
335n/a packdir2 + TESTMOD + pyc_ext: (NOW, test_pyc)}
336n/a zip1 = os.path.abspath("path1.zip")
337n/a self.makeZip(files1, zip1)
338n/a
339n/a files2 = {packdir: (NOW, ""),
340n/a packdir + TESTMOD + '2' + pyc_ext: (NOW, test_pyc),
341n/a packdir2: (NOW, ""),
342n/a packdir2 + TESTMOD + '2' + pyc_ext: (NOW, test_pyc),
343n/a packdir2 + TESTMOD + pyc_ext: (NOW, test_pyc)}
344n/a zip2 = os.path.abspath("path2.zip")
345n/a self.makeZip(files2, zip2)
346n/a
347n/a # zip2 should override zip1.
348n/a sys.path.insert(0, zip1)
349n/a sys.path.insert(0, zip2)
350n/a
351n/a mod = importlib.import_module(TESTPACK)
352n/a
353n/a # if TESTPACK is functioning as a namespace pkg then
354n/a # there should be two entries in the __path__.
355n/a # First should be path2 and second path1.
356n/a self.assertEqual(2, len(mod.__path__))
357n/a p1, p2 = mod.__path__
358n/a self.assertEqual("path2.zip", p1.split(os.sep)[-2])
359n/a self.assertEqual("path1.zip", p2.split(os.sep)[-2])
360n/a
361n/a # packdir3 should import as a namespace package.
362n/a # Tts __path__ is an iterable of 1 element from zip1.
363n/a mod = importlib.import_module(packdir3.replace(os.sep, '.')[:-1])
364n/a self.assertEqual(1, len(mod.__path__))
365n/a mpath = list(mod.__path__)[0].split('path1.zip' + os.sep)[1]
366n/a self.assertEqual(packdir3[:-1], mpath)
367n/a
368n/a # TESTPACK/TESTMOD only exists in path1.
369n/a mod = importlib.import_module('.'.join((TESTPACK, TESTMOD)))
370n/a self.assertEqual("path1.zip", mod.__file__.split(os.sep)[-3])
371n/a
372n/a # And TESTPACK/(TESTMOD + '2') only exists in path2.
373n/a mod = importlib.import_module('.'.join((TESTPACK, TESTMOD + '2')))
374n/a self.assertEqual("path2.zip", mod.__file__.split(os.sep)[-3])
375n/a
376n/a # One level deeper...
377n/a subpkg = '.'.join((TESTPACK, TESTPACK2))
378n/a mod = importlib.import_module(subpkg)
379n/a self.assertEqual(2, len(mod.__path__))
380n/a p1, p2 = mod.__path__
381n/a self.assertEqual("path2.zip", p1.split(os.sep)[-3])
382n/a self.assertEqual("path1.zip", p2.split(os.sep)[-3])
383n/a
384n/a # subpkg.TESTMOD exists in both zips should load from zip2.
385n/a mod = importlib.import_module('.'.join((subpkg, TESTMOD)))
386n/a self.assertEqual('path2.zip', mod.__file__.split(os.sep)[-4])
387n/a
388n/a # subpkg.TESTMOD + '2' only exists in zip2.
389n/a mod = importlib.import_module('.'.join((subpkg, TESTMOD + '2')))
390n/a self.assertEqual('path2.zip', mod.__file__.split(os.sep)[-4])
391n/a
392n/a # Finally subpkg.TESTMOD + '3' only exists in zip1.
393n/a mod = importlib.import_module('.'.join((subpkg, TESTMOD + '3')))
394n/a self.assertEqual('path1.zip', mod.__file__.split(os.sep)[-4])
395n/a
396n/a def testZipImporterMethods(self):
397n/a packdir = TESTPACK + os.sep
398n/a packdir2 = packdir + TESTPACK2 + os.sep
399n/a files = {packdir + "__init__" + pyc_ext: (NOW, test_pyc),
400n/a packdir2 + "__init__" + pyc_ext: (NOW, test_pyc),
401n/a packdir2 + TESTMOD + pyc_ext: (NOW, test_pyc),
402n/a "spam" + pyc_ext: (NOW, test_pyc)}
403n/a
404n/a z = ZipFile(TEMP_ZIP, "w")
405n/a try:
406n/a for name, (mtime, data) in files.items():
407n/a zinfo = ZipInfo(name, time.localtime(mtime))
408n/a zinfo.compress_type = self.compression
409n/a zinfo.comment = b"spam"
410n/a z.writestr(zinfo, data)
411n/a z.close()
412n/a
413n/a zi = zipimport.zipimporter(TEMP_ZIP)
414n/a self.assertEqual(zi.archive, TEMP_ZIP)
415n/a self.assertEqual(zi.is_package(TESTPACK), True)
416n/a
417n/a find_mod = zi.find_module('spam')
418n/a self.assertIsNotNone(find_mod)
419n/a self.assertIsInstance(find_mod, zipimport.zipimporter)
420n/a self.assertFalse(find_mod.is_package('spam'))
421n/a load_mod = find_mod.load_module('spam')
422n/a self.assertEqual(find_mod.get_filename('spam'), load_mod.__file__)
423n/a
424n/a mod = zi.load_module(TESTPACK)
425n/a self.assertEqual(zi.get_filename(TESTPACK), mod.__file__)
426n/a
427n/a existing_pack_path = importlib.import_module(TESTPACK).__path__[0]
428n/a expected_path_path = os.path.join(TEMP_ZIP, TESTPACK)
429n/a self.assertEqual(existing_pack_path, expected_path_path)
430n/a
431n/a self.assertEqual(zi.is_package(packdir + '__init__'), False)
432n/a self.assertEqual(zi.is_package(packdir + TESTPACK2), True)
433n/a self.assertEqual(zi.is_package(packdir2 + TESTMOD), False)
434n/a
435n/a mod_path = packdir2 + TESTMOD
436n/a mod_name = module_path_to_dotted_name(mod_path)
437n/a mod = importlib.import_module(mod_name)
438n/a self.assertTrue(mod_name in sys.modules)
439n/a self.assertEqual(zi.get_source(TESTPACK), None)
440n/a self.assertEqual(zi.get_source(mod_path), None)
441n/a self.assertEqual(zi.get_filename(mod_path), mod.__file__)
442n/a # To pass in the module name instead of the path, we must use the
443n/a # right importer
444n/a loader = mod.__loader__
445n/a self.assertEqual(loader.get_source(mod_name), None)
446n/a self.assertEqual(loader.get_filename(mod_name), mod.__file__)
447n/a
448n/a # test prefix and archivepath members
449n/a zi2 = zipimport.zipimporter(TEMP_ZIP + os.sep + TESTPACK)
450n/a self.assertEqual(zi2.archive, TEMP_ZIP)
451n/a self.assertEqual(zi2.prefix, TESTPACK + os.sep)
452n/a finally:
453n/a z.close()
454n/a os.remove(TEMP_ZIP)
455n/a
456n/a def testZipImporterMethodsInSubDirectory(self):
457n/a packdir = TESTPACK + os.sep
458n/a packdir2 = packdir + TESTPACK2 + os.sep
459n/a files = {packdir2 + "__init__" + pyc_ext: (NOW, test_pyc),
460n/a packdir2 + TESTMOD + pyc_ext: (NOW, test_pyc)}
461n/a
462n/a z = ZipFile(TEMP_ZIP, "w")
463n/a try:
464n/a for name, (mtime, data) in files.items():
465n/a zinfo = ZipInfo(name, time.localtime(mtime))
466n/a zinfo.compress_type = self.compression
467n/a zinfo.comment = b"eggs"
468n/a z.writestr(zinfo, data)
469n/a z.close()
470n/a
471n/a zi = zipimport.zipimporter(TEMP_ZIP + os.sep + packdir)
472n/a self.assertEqual(zi.archive, TEMP_ZIP)
473n/a self.assertEqual(zi.prefix, packdir)
474n/a self.assertEqual(zi.is_package(TESTPACK2), True)
475n/a mod = zi.load_module(TESTPACK2)
476n/a self.assertEqual(zi.get_filename(TESTPACK2), mod.__file__)
477n/a
478n/a self.assertEqual(
479n/a zi.is_package(TESTPACK2 + os.sep + '__init__'), False)
480n/a self.assertEqual(
481n/a zi.is_package(TESTPACK2 + os.sep + TESTMOD), False)
482n/a
483n/a pkg_path = TEMP_ZIP + os.sep + packdir + TESTPACK2
484n/a zi2 = zipimport.zipimporter(pkg_path)
485n/a find_mod_dotted = zi2.find_module(TESTMOD)
486n/a self.assertIsNotNone(find_mod_dotted)
487n/a self.assertIsInstance(find_mod_dotted, zipimport.zipimporter)
488n/a self.assertFalse(zi2.is_package(TESTMOD))
489n/a load_mod = find_mod_dotted.load_module(TESTMOD)
490n/a self.assertEqual(
491n/a find_mod_dotted.get_filename(TESTMOD), load_mod.__file__)
492n/a
493n/a mod_path = TESTPACK2 + os.sep + TESTMOD
494n/a mod_name = module_path_to_dotted_name(mod_path)
495n/a mod = importlib.import_module(mod_name)
496n/a self.assertTrue(mod_name in sys.modules)
497n/a self.assertEqual(zi.get_source(TESTPACK2), None)
498n/a self.assertEqual(zi.get_source(mod_path), None)
499n/a self.assertEqual(zi.get_filename(mod_path), mod.__file__)
500n/a # To pass in the module name instead of the path, we must use the
501n/a # right importer.
502n/a loader = mod.__loader__
503n/a self.assertEqual(loader.get_source(mod_name), None)
504n/a self.assertEqual(loader.get_filename(mod_name), mod.__file__)
505n/a finally:
506n/a z.close()
507n/a os.remove(TEMP_ZIP)
508n/a
509n/a def testGetData(self):
510n/a z = ZipFile(TEMP_ZIP, "w")
511n/a z.compression = self.compression
512n/a try:
513n/a name = "testdata.dat"
514n/a data = bytes(x for x in range(256))
515n/a z.writestr(name, data)
516n/a z.close()
517n/a zi = zipimport.zipimporter(TEMP_ZIP)
518n/a self.assertEqual(data, zi.get_data(name))
519n/a self.assertIn('zipimporter object', repr(zi))
520n/a finally:
521n/a z.close()
522n/a os.remove(TEMP_ZIP)
523n/a
524n/a def testImporterAttr(self):
525n/a src = """if 1: # indent hack
526n/a def get_file():
527n/a return __file__
528n/a if __loader__.get_data("some.data") != b"some data":
529n/a raise AssertionError("bad data")\n"""
530n/a pyc = make_pyc(compile(src, "<???>", "exec"), NOW, len(src))
531n/a files = {TESTMOD + pyc_ext: (NOW, pyc),
532n/a "some.data": (NOW, "some data")}
533n/a self.doTest(pyc_ext, files, TESTMOD)
534n/a
535n/a def testDefaultOptimizationLevel(self):
536n/a # zipimport should use the default optimization level (#28131)
537n/a src = """if 1: # indent hack
538n/a def test(val):
539n/a assert(val)
540n/a return val\n"""
541n/a files = {TESTMOD + '.py': (NOW, src)}
542n/a self.makeZip(files)
543n/a sys.path.insert(0, TEMP_ZIP)
544n/a mod = importlib.import_module(TESTMOD)
545n/a self.assertEqual(mod.test(1), 1)
546n/a self.assertRaises(AssertionError, mod.test, False)
547n/a
548n/a def testImport_WithStuff(self):
549n/a # try importing from a zipfile which contains additional
550n/a # stuff at the beginning of the file
551n/a files = {TESTMOD + ".py": (NOW, test_src)}
552n/a self.doTest(".py", files, TESTMOD,
553n/a stuff=b"Some Stuff"*31)
554n/a
555n/a def assertModuleSource(self, module):
556n/a self.assertEqual(inspect.getsource(module), test_src)
557n/a
558n/a def testGetSource(self):
559n/a files = {TESTMOD + ".py": (NOW, test_src)}
560n/a self.doTest(".py", files, TESTMOD, call=self.assertModuleSource)
561n/a
562n/a def testGetCompiledSource(self):
563n/a pyc = make_pyc(compile(test_src, "<???>", "exec"), NOW, len(test_src))
564n/a files = {TESTMOD + ".py": (NOW, test_src),
565n/a TESTMOD + pyc_ext: (NOW, pyc)}
566n/a self.doTest(pyc_ext, files, TESTMOD, call=self.assertModuleSource)
567n/a
568n/a def runDoctest(self, callback):
569n/a files = {TESTMOD + ".py": (NOW, test_src),
570n/a "xyz.txt": (NOW, ">>> log.append(True)\n")}
571n/a self.doTest(".py", files, TESTMOD, call=callback)
572n/a
573n/a def doDoctestFile(self, module):
574n/a log = []
575n/a old_master, doctest.master = doctest.master, None
576n/a try:
577n/a doctest.testfile(
578n/a 'xyz.txt', package=module, module_relative=True,
579n/a globs=locals()
580n/a )
581n/a finally:
582n/a doctest.master = old_master
583n/a self.assertEqual(log,[True])
584n/a
585n/a def testDoctestFile(self):
586n/a self.runDoctest(self.doDoctestFile)
587n/a
588n/a def doDoctestSuite(self, module):
589n/a log = []
590n/a doctest.DocFileTest(
591n/a 'xyz.txt', package=module, module_relative=True,
592n/a globs=locals()
593n/a ).run()
594n/a self.assertEqual(log,[True])
595n/a
596n/a def testDoctestSuite(self):
597n/a self.runDoctest(self.doDoctestSuite)
598n/a
599n/a def doTraceback(self, module):
600n/a try:
601n/a module.do_raise()
602n/a except:
603n/a tb = sys.exc_info()[2].tb_next
604n/a
605n/a f,lno,n,line = extract_tb(tb, 1)[0]
606n/a self.assertEqual(line, raise_src.strip())
607n/a
608n/a f,lno,n,line = extract_stack(tb.tb_frame, 1)[0]
609n/a self.assertEqual(line, raise_src.strip())
610n/a
611n/a s = io.StringIO()
612n/a print_tb(tb, 1, s)
613n/a self.assertTrue(s.getvalue().endswith(raise_src))
614n/a else:
615n/a raise AssertionError("This ought to be impossible")
616n/a
617n/a def testTraceback(self):
618n/a files = {TESTMOD + ".py": (NOW, raise_src)}
619n/a self.doTest(None, files, TESTMOD, call=self.doTraceback)
620n/a
621n/a @unittest.skipIf(support.TESTFN_UNENCODABLE is None,
622n/a "need an unencodable filename")
623n/a def testUnencodable(self):
624n/a filename = support.TESTFN_UNENCODABLE + ".zip"
625n/a z = ZipFile(filename, "w")
626n/a zinfo = ZipInfo(TESTMOD + ".py", time.localtime(NOW))
627n/a zinfo.compress_type = self.compression
628n/a z.writestr(zinfo, test_src)
629n/a z.close()
630n/a try:
631n/a zipimport.zipimporter(filename).load_module(TESTMOD)
632n/a finally:
633n/a os.remove(filename)
634n/a
635n/a def testBytesPath(self):
636n/a filename = support.TESTFN + ".zip"
637n/a self.addCleanup(support.unlink, filename)
638n/a with ZipFile(filename, "w") as z:
639n/a zinfo = ZipInfo(TESTMOD + ".py", time.localtime(NOW))
640n/a zinfo.compress_type = self.compression
641n/a z.writestr(zinfo, test_src)
642n/a
643n/a zipimport.zipimporter(filename)
644n/a zipimport.zipimporter(os.fsencode(filename))
645n/a with self.assertWarns(DeprecationWarning):
646n/a zipimport.zipimporter(bytearray(os.fsencode(filename)))
647n/a with self.assertWarns(DeprecationWarning):
648n/a zipimport.zipimporter(memoryview(os.fsencode(filename)))
649n/a
650n/a
651n/a@support.requires_zlib
652n/aclass CompressedZipImportTestCase(UncompressedZipImportTestCase):
653n/a compression = ZIP_DEFLATED
654n/a
655n/a
656n/aclass BadFileZipImportTestCase(unittest.TestCase):
657n/a def assertZipFailure(self, filename):
658n/a self.assertRaises(zipimport.ZipImportError,
659n/a zipimport.zipimporter, filename)
660n/a
661n/a def testNoFile(self):
662n/a self.assertZipFailure('AdfjdkFJKDFJjdklfjs')
663n/a
664n/a def testEmptyFilename(self):
665n/a self.assertZipFailure('')
666n/a
667n/a def testBadArgs(self):
668n/a self.assertRaises(TypeError, zipimport.zipimporter, None)
669n/a self.assertRaises(TypeError, zipimport.zipimporter, TESTMOD, kwd=None)
670n/a self.assertRaises(TypeError, zipimport.zipimporter,
671n/a list(os.fsencode(TESTMOD)))
672n/a
673n/a def testFilenameTooLong(self):
674n/a self.assertZipFailure('A' * 33000)
675n/a
676n/a def testEmptyFile(self):
677n/a support.unlink(TESTMOD)
678n/a support.create_empty_file(TESTMOD)
679n/a self.assertZipFailure(TESTMOD)
680n/a
681n/a def testFileUnreadable(self):
682n/a support.unlink(TESTMOD)
683n/a fd = os.open(TESTMOD, os.O_CREAT, 000)
684n/a try:
685n/a os.close(fd)
686n/a
687n/a with self.assertRaises(zipimport.ZipImportError) as cm:
688n/a zipimport.zipimporter(TESTMOD)
689n/a finally:
690n/a # If we leave "the read-only bit" set on Windows, nothing can
691n/a # delete TESTMOD, and later tests suffer bogus failures.
692n/a os.chmod(TESTMOD, 0o666)
693n/a support.unlink(TESTMOD)
694n/a
695n/a def testNotZipFile(self):
696n/a support.unlink(TESTMOD)
697n/a fp = open(TESTMOD, 'w+')
698n/a fp.write('a' * 22)
699n/a fp.close()
700n/a self.assertZipFailure(TESTMOD)
701n/a
702n/a # XXX: disabled until this works on Big-endian machines
703n/a def _testBogusZipFile(self):
704n/a support.unlink(TESTMOD)
705n/a fp = open(TESTMOD, 'w+')
706n/a fp.write(struct.pack('=I', 0x06054B50))
707n/a fp.write('a' * 18)
708n/a fp.close()
709n/a z = zipimport.zipimporter(TESTMOD)
710n/a
711n/a try:
712n/a self.assertRaises(TypeError, z.find_module, None)
713n/a self.assertRaises(TypeError, z.load_module, None)
714n/a self.assertRaises(TypeError, z.is_package, None)
715n/a self.assertRaises(TypeError, z.get_code, None)
716n/a self.assertRaises(TypeError, z.get_data, None)
717n/a self.assertRaises(TypeError, z.get_source, None)
718n/a
719n/a error = zipimport.ZipImportError
720n/a self.assertEqual(z.find_module('abc'), None)
721n/a
722n/a self.assertRaises(error, z.load_module, 'abc')
723n/a self.assertRaises(error, z.get_code, 'abc')
724n/a self.assertRaises(OSError, z.get_data, 'abc')
725n/a self.assertRaises(error, z.get_source, 'abc')
726n/a self.assertRaises(error, z.is_package, 'abc')
727n/a finally:
728n/a zipimport._zip_directory_cache.clear()
729n/a
730n/a
731n/adef test_main():
732n/a try:
733n/a support.run_unittest(
734n/a UncompressedZipImportTestCase,
735n/a CompressedZipImportTestCase,
736n/a BadFileZipImportTestCase,
737n/a )
738n/a finally:
739n/a support.unlink(TESTMOD)
740n/a
741n/aif __name__ == "__main__":
742n/a test_main()