import zlib
# implied prerequisite
from zipfile
import ZipFile
, ZipInfo
, ZIP_STORED
, ZIP_DEFLATED
from test
import test_support
from test
.test_importhooks
import ImportHooksBaseTestCase
, test_src
, test_co
if type(mtime
) is type(0.0):
# Mac mtimes need a bit of special casing
mtime
= int(-0x100000000L
+ long(mtime
))
pyc
= imp
.get_magic() + struct
.pack("<i", int(mtime
)) + data
test_pyc
= make_pyc(test_co
, NOW
)
TESTMOD
= "ziptestmodule"
TESTPACK
= "ziptestpackage"
TESTPACK2
= "ziptestpackage2"
TEMP_ZIP
= os
.path
.abspath("junk95142" + os
.extsep
+ "zip")
class UncompressedZipImportTestCase(ImportHooksBaseTestCase
):
# We're reusing the zip archive path, so we must clear the
zipimport
._zip
_directory
_cache
.clear()
ImportHooksBaseTestCase
.setUp(self
)
def doTest(self
, expected_ext
, files
, *modules
, **kw
):
z
= ZipFile(TEMP_ZIP
, "w")
for name
, (mtime
, data
) in files
.items():
zinfo
= ZipInfo(name
, time
.localtime(mtime
))
zinfo
.compress_type
= self
.compression
stuff
= kw
.get("stuff", None)
# Prepend 'stuff' to the start of the zipfile
sys
.path
.insert(0, TEMP_ZIP
)
mod
= __import__(".".join(modules
), globals(), locals(),
self
.assertEquals(file, os
.path
.join(TEMP_ZIP
,
*modules
) + expected_ext
)
# This could cause a stack overflow before: importing zlib.py
# from a compressed archive would cause zlib to be imported
# which would find zlib.py in the archive, which would... etc.
# This test *must* be executed first: it must be the first one
# to trigger zipimport to import zlib (zipimport caches the
# zlib.decompress function object, after which the problem being
# tested here wouldn't be a problem anymore...
# (Hence the 'A' in the test method name: to make it the first
# item in a list sorted by name, like unittest.makeSuite() does.)
# This test fails on platforms on which the zlib module is
# statically linked, but the problem it tests for can't
# occur in that case (builtin modules are always found first),
# so we'll simply skip it then. Bug #765456.
if "zlib" in sys
.builtin_module_names
:
if "zlib" in sys
.modules
:
files
= {"zlib.py": (NOW
, test_src
)}
self
.doTest(".py", files
, "zlib")
if self
.compression
!= ZIP_DEFLATED
:
self
.fail("expected test to not raise ImportError")
if self
.compression
!= ZIP_STORED
:
self
.fail("expected test to raise ImportError")
files
= {TESTMOD
+ ".py": (NOW
, test_src
)}
self
.doTest(".py", files
, TESTMOD
)
files
= {TESTMOD
+ pyc_ext
: (NOW
, test_pyc
)}
self
.doTest(pyc_ext
, files
, TESTMOD
)
files
= {TESTMOD
+ ".py": (NOW
, test_src
),
TESTMOD
+ pyc_ext
: (NOW
, test_pyc
)}
self
.doTest(pyc_ext
, files
, TESTMOD
)
files
= {TESTMOD
+ ".py": (NOW
, "")}
self
.doTest(None, files
, TESTMOD
)
# make pyc magic word invalid, forcing loading from .py
m0 ^
= 0x04 # flip an arbitrary bit
badmagic_pyc
= chr(m0
) + test_pyc
[1:]
files
= {TESTMOD
+ ".py": (NOW
, test_src
),
TESTMOD
+ pyc_ext
: (NOW
, badmagic_pyc
)}
self
.doTest(".py", files
, TESTMOD
)
# make pyc magic word invalid, causing an ImportError
m0 ^
= 0x04 # flip an arbitrary bit
badmagic_pyc
= chr(m0
) + test_pyc
[1:]
files
= {TESTMOD
+ pyc_ext
: (NOW
, badmagic_pyc
)}
self
.doTest(".py", files
, TESTMOD
)
self
.fail("expected ImportError; import from bad pyc")
t3 ^
= 0x02 # flip the second bit -- not the first as that one
# isn't stored in the .py's mtime in the zip archive.
badtime_pyc
= test_pyc
[:7] + chr(t3
) + test_pyc
[8:]
files
= {TESTMOD
+ ".py": (NOW
, test_src
),
TESTMOD
+ pyc_ext
: (NOW
, badtime_pyc
)}
self
.doTest(".py", files
, TESTMOD
)
packdir
= TESTPACK
+ os
.sep
files
= {packdir
+ "__init__" + pyc_ext
: (NOW
, test_pyc
),
packdir
+ TESTMOD
+ pyc_ext
: (NOW
, test_pyc
)}
self
.doTest(pyc_ext
, files
, TESTPACK
, TESTMOD
)
def testDeepPackage(self
):
packdir
= TESTPACK
+ os
.sep
packdir2
= packdir
+ TESTPACK2
+ os
.sep
files
= {packdir
+ "__init__" + pyc_ext
: (NOW
, test_pyc
),
packdir2
+ "__init__" + pyc_ext
: (NOW
, test_pyc
),
packdir2
+ TESTMOD
+ pyc_ext
: (NOW
, test_pyc
)}
self
.doTest(pyc_ext
, files
, TESTPACK
, TESTPACK2
, TESTMOD
)
z
= ZipFile(TEMP_ZIP
, "w")
z
.compression
= self
.compression
data
= "".join([chr(x
) for x
in range(256)]) * 500
zi
= zipimport
.zipimporter(TEMP_ZIP
)
self
.assertEquals(data
, zi
.get_data(name
))
def testImporterAttr(self
):
src
= """if 1: # indent hack
if __loader__.get_data("some.data") != "some data":
raise AssertionError, "bad data"\n"""
pyc
= make_pyc(compile(src
, "<???>", "exec"), NOW
)
files
= {TESTMOD
+ pyc_ext
: (NOW
, pyc
),
"some.data": (NOW
, "some data")}
self
.doTest(pyc_ext
, files
, TESTMOD
)
def testImport_WithStuff(self
):
# try importing from a zipfile which contains additional
# stuff at the beginning of the file
files
= {TESTMOD
+ ".py": (NOW
, test_src
)}
self
.doTest(".py", files
, TESTMOD
,
class CompressedZipImportTestCase(UncompressedZipImportTestCase
):
compression
= ZIP_DEFLATED
test_support
.run_unittest(
UncompressedZipImportTestCase
,
CompressedZipImportTestCase
if __name__
== "__main__":