Index: Doc/library/zipimport.rst =================================================================== --- Doc/library/zipimport.rst (revision 59333) +++ Doc/library/zipimport.rst (working copy) @@ -71,11 +71,20 @@ .. class:: zipimporter(archivepath) - Create a new zipimporter instance. *archivepath* must be a path to a zipfile. + Create a new zipimporter instance. *archivepath* must be a path to a + zipfile, or to a specific path inside a zipfile. For example, it can be + */tmp/myimport.zip*, or */tmp/myimport.zip/mydirectory*, if mydirectory is a + valid directory inside the archive. + :exc:`ZipImportError` is raised if *archivepath* doesn't point to a valid ZIP archive. +.. attribute:: zimporter.archive + + The name of the zipfile targeted, without the subpath (read-only). + + .. method:: zipimporter.find_module(fullname[, path]) Search for a module specified by *fullname*. *fullname* must be the fully Index: Lib/test/test_zipimport.py =================================================================== --- Lib/test/test_zipimport.py (revision 59333) +++ Lib/test/test_zipimport.py (working copy) @@ -212,6 +212,7 @@ z.close() zi = zipimport.zipimporter(TEMP_ZIP) + self.assertEquals(zi.archive, TEMP_ZIP) self.assertEquals(zi.is_package(TESTPACK), True) zi.load_module(TESTPACK) @@ -227,6 +228,36 @@ 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.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 Index: Modules/zipimport.c =================================================================== --- Modules/zipimport.c (revision 59333) +++ Modules/zipimport.c (working copy) @@ -555,8 +555,15 @@ "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 is a read-only copy of the\n\ +name of the zipfile targeted."); #define DEFERRED_ADDRESS(ADDR) 0