From 6a57c08dc828ff8512c047c97e7c7edfb0abbc74 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sun, 11 May 2008 15:05:13 +0000 Subject: [PATCH] #1326: document and test zipimporter.archive and zipimporter.prefix. --- Doc/library/zipimport.rst | 25 ++++++++++++++----------- Lib/test/test_zipimport.py | 32 ++++++++++++++++++++++++++++++++ Modules/zipimport.c | 11 +++++++++-- 3 files changed, 55 insertions(+), 13 deletions(-) diff --git a/Doc/library/zipimport.rst b/Doc/library/zipimport.rst index 0e8770c53ed..104182e7e8c 100644 --- a/Doc/library/zipimport.rst +++ b/Doc/library/zipimport.rst @@ -65,17 +65,14 @@ zipimporter Objects .. class:: zipimporter(archivepath) - Create a new zipimporter instance. *archivepath* must be a path to a ZIP file. + Create a new zipimporter instance. *archivepath* must be a path to a ZIP + file, or to a specific path within a ZIP file. For example, an *archivepath* + of :file:`foo/bar.zip/lib` will look for modules in the :file:`lib` directory + inside the ZIP file :file:`foo/bar.zip` (provided that it exists). + :exc:`ZipImportError` is raised if *archivepath* doesn't point to a valid ZIP archive. - *archivepath* can also contain a path within the ZIP file -- the importer - object will then look under that path instead of the ZIP file root. For - example, an *archivepath* of :file:`foo/bar.zip/lib` will look for modules - in the :file:`lib` directory inside the ZIP file :file:`foo/bar.zip` - (provided that it exists). - - .. method:: find_module(fullname[, path]) Search for a module specified by *fullname*. *fullname* must be the fully @@ -120,13 +117,19 @@ zipimporter Objects .. attribute:: archive - The file name of the importer's associated ZIP file. + The file name of the importer's associated ZIP file, without a possible + subpath. .. attribute:: prefix - The path within the ZIP file where modules are searched; see - :class:`zipimporter` for details. + The subpath within the ZIP file where modules are searched. This is the + empty string for zipimporter objects which point to the root of the ZIP + file. + + The :attr:`archive` and :attr:`prefix` attributes, when combined with a + slash, equal the original *archivepath* argument given to the + :class:`zipimporter` constructor. .. _zipimport-examples: diff --git a/Lib/test/test_zipimport.py b/Lib/test/test_zipimport.py index 7ce0cf44fcb..205853d1866 100644 --- a/Lib/test/test_zipimport.py +++ b/Lib/test/test_zipimport.py @@ -212,6 +212,7 @@ class UncompressedZipImportTestCase(ImportHooksBaseTestCase): z.close() zi = zipimport.zipimporter(TEMP_ZIP) + self.assertEquals(zi.archive, TEMP_ZIP) self.assertEquals(zi.is_package(TESTPACK), True) zi.load_module(TESTPACK) @@ -232,6 +233,37 @@ class UncompressedZipImportTestCase(ImportHooksBaseTestCase): z.close() os.remove(TEMP_ZIP) + def testZipImporterMethodsInSubDirectory(self): + packdir = TESTPACK + os.sep + packdir2 = packdir + TESTPACK2 + os.sep + files = {packdir2 + "__init__" + pyc_ext: (NOW, test_pyc), + packdir2 + TESTMOD + pyc_ext: (NOW, test_pyc)} + + z = ZipFile(TEMP_ZIP, "w") + try: + for name, (mtime, data) in files.items(): + zinfo = ZipInfo(name, time.localtime(mtime)) + zinfo.compress_type = self.compression + z.writestr(zinfo, data) + z.close() + + zi = zipimport.zipimporter(TEMP_ZIP + os.sep + packdir) + self.assertEquals(zi.archive, TEMP_ZIP) + self.assertEquals(zi.prefix, packdir) + self.assertEquals(zi.is_package(TESTPACK2), True) + zi.load_module(TESTPACK2) + + self.assertEquals(zi.is_package(TESTPACK2 + os.sep + '__init__'), False) + self.assertEquals(zi.is_package(TESTPACK2 + os.sep + TESTMOD), False) + + mod_name = TESTPACK2 + os.sep + TESTMOD + mod = __import__(module_path_to_dotted_name(mod_name)) + self.assertEquals(zi.get_source(TESTPACK2), None) + self.assertEquals(zi.get_source(mod_name), None) + finally: + z.close() + os.remove(TEMP_ZIP) + def testGetData(self): z = ZipFile(TEMP_ZIP, "w") z.compression = self.compression diff --git a/Modules/zipimport.c b/Modules/zipimport.c index a57812d6a48..d3cd4ad61a7 100644 --- a/Modules/zipimport.c +++ b/Modules/zipimport.c @@ -555,8 +555,15 @@ PyDoc_STRVAR(zipimporter_doc, "zipimporter(archivepath) -> zipimporter object\n\ \n\ Create a new zipimporter instance. 'archivepath' must be a path to\n\ -a zipfile. ZipImportError is raised if 'archivepath' doesn't point to\n\ -a valid Zip archive."); +a zipfile, or to a specific path inside a zipfile. For example, it can be\n\ +'/tmp/myimport.zip', or '/tmp/myimport.zip/mydirectory', if mydirectory is a\n\ +valid directory inside the archive.\n\ +\n\ +'ZipImportError is raised if 'archivepath' doesn't point to a valid Zip\n\ +archive.\n\ +\n\ +The 'archive' attribute of zipimporter objects contains the name of the\n\ +zipfile targeted."); #define DEFERRED_ADDRESS(ADDR) 0