]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/python/contrib/Lib/test/test_import.py
Inital import
[l4.git] / l4 / pkg / python / contrib / Lib / test / test_import.py
1 import unittest
2 import os
3 import stat
4 import random
5 import shutil
6 import sys
7 import py_compile
8 import warnings
9 import marshal
10 from test.test_support import (unlink, TESTFN, unload, run_unittest,
11     check_warnings, TestFailed)
12
13
14 def remove_files(name):
15     for f in (name + os.extsep + "py",
16               name + os.extsep + "pyc",
17               name + os.extsep + "pyo",
18               name + os.extsep + "pyw",
19               name + "$py.class"):
20         if os.path.exists(f):
21             os.remove(f)
22
23
24 class ImportTest(unittest.TestCase):
25
26     def testCaseSensitivity(self):
27         # Brief digression to test that import is case-sensitive:  if we got this
28         # far, we know for sure that "random" exists.
29         try:
30             import RAnDoM
31         except ImportError:
32             pass
33         else:
34             self.fail("import of RAnDoM should have failed (case mismatch)")
35
36     def testDoubleConst(self):
37         # Another brief digression to test the accuracy of manifest float constants.
38         from test import double_const  # don't blink -- that *was* the test
39
40     def testImport(self):
41         def test_with_extension(ext):
42             # ext normally ".py"; perhaps ".pyw"
43             source = TESTFN + ext
44             pyo = TESTFN + os.extsep + "pyo"
45             if sys.platform.startswith('java'):
46                 pyc = TESTFN + "$py.class"
47             else:
48                 pyc = TESTFN + os.extsep + "pyc"
49
50             f = open(source, "w")
51             print >> f, "# This tests Python's ability to import a", ext, "file."
52             a = random.randrange(1000)
53             b = random.randrange(1000)
54             print >> f, "a =", a
55             print >> f, "b =", b
56             f.close()
57
58             try:
59                 try:
60                     mod = __import__(TESTFN)
61                 except ImportError, err:
62                     self.fail("import from %s failed: %s" % (ext, err))
63
64                 self.assertEquals(mod.a, a,
65                     "module loaded (%s) but contents invalid" % mod)
66                 self.assertEquals(mod.b, b,
67                     "module loaded (%s) but contents invalid" % mod)
68             finally:
69                 os.unlink(source)
70
71             try:
72                 try:
73                     reload(mod)
74                 except ImportError, err:
75                     self.fail("import from .pyc/.pyo failed: %s" % err)
76             finally:
77                 try:
78                     os.unlink(pyc)
79                 except OSError:
80                     pass
81                 try:
82                     os.unlink(pyo)
83                 except OSError:
84                     pass
85                 del sys.modules[TESTFN]
86
87         sys.path.insert(0, os.curdir)
88         try:
89             test_with_extension(os.extsep + "py")
90             if sys.platform.startswith("win"):
91                 for ext in ".PY", ".Py", ".pY", ".pyw", ".PYW", ".pYw":
92                     test_with_extension(ext)
93         finally:
94             del sys.path[0]
95
96     if os.name == 'posix':
97         def test_execute_bit_not_copied(self):
98             # Issue 6070: under posix .pyc files got their execute bit set if
99             # the .py file had the execute bit set, but they aren't executable.
100             oldmask = os.umask(022)
101             sys.path.insert(0, os.curdir)
102             try:
103                 fname = TESTFN + os.extsep + "py"
104                 f = open(fname, 'w').close()
105                 os.chmod(fname, (stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH |
106                                  stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH))
107                 __import__(TESTFN)
108                 fn = fname + 'c'
109                 if not os.path.exists(fn):
110                     fn = fname + 'o'
111                     if not os.path.exists(fn): raise TestFailed("__import__ did "
112                         "not result in creation of either a .pyc or .pyo file")
113                 s = os.stat(fn)
114                 self.assertEquals(stat.S_IMODE(s.st_mode),
115                                   stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH)
116             finally:
117                 os.umask(oldmask)
118                 remove_files(TESTFN)
119                 if TESTFN in sys.modules: del sys.modules[TESTFN]
120                 del sys.path[0]
121
122     def testImpModule(self):
123         # Verify that the imp module can correctly load and find .py files
124         import imp
125         x = imp.find_module("os")
126         os = imp.load_module("os", *x)
127
128     def test_module_with_large_stack(self, module='longlist'):
129         # create module w/list of 65000 elements to test bug #561858
130         filename = module + os.extsep + 'py'
131
132         # create a file with a list of 65000 elements
133         f = open(filename, 'w+')
134         f.write('d = [\n')
135         for i in range(65000):
136             f.write('"",\n')
137         f.write(']')
138         f.close()
139
140         # compile & remove .py file, we only need .pyc (or .pyo)
141         f = open(filename, 'r')
142         py_compile.compile(filename)
143         f.close()
144         os.unlink(filename)
145
146         # need to be able to load from current dir
147         sys.path.append('')
148
149         # this used to crash
150         exec 'import ' + module
151
152         # cleanup
153         del sys.path[-1]
154         for ext in 'pyc', 'pyo':
155             fname = module + os.extsep + ext
156             if os.path.exists(fname):
157                 os.unlink(fname)
158
159     def test_failing_import_sticks(self):
160         source = TESTFN + os.extsep + "py"
161         f = open(source, "w")
162         print >> f, "a = 1/0"
163         f.close()
164
165         # New in 2.4, we shouldn't be able to import that no matter how often
166         # we try.
167         sys.path.insert(0, os.curdir)
168         try:
169             for i in 1, 2, 3:
170                 try:
171                     mod = __import__(TESTFN)
172                 except ZeroDivisionError:
173                     if TESTFN in sys.modules:
174                         self.fail("damaged module in sys.modules on %i. try" % i)
175                 else:
176                     self.fail("was able to import a damaged module on %i. try" % i)
177         finally:
178             sys.path.pop(0)
179             remove_files(TESTFN)
180
181     def test_failing_reload(self):
182         # A failing reload should leave the module object in sys.modules.
183         source = TESTFN + os.extsep + "py"
184         f = open(source, "w")
185         print >> f, "a = 1"
186         print >> f, "b = 2"
187         f.close()
188
189         sys.path.insert(0, os.curdir)
190         try:
191             mod = __import__(TESTFN)
192             self.assert_(TESTFN in sys.modules, "expected module in sys.modules")
193             self.assertEquals(mod.a, 1, "module has wrong attribute values")
194             self.assertEquals(mod.b, 2, "module has wrong attribute values")
195
196             # On WinXP, just replacing the .py file wasn't enough to
197             # convince reload() to reparse it.  Maybe the timestamp didn't
198             # move enough.  We force it to get reparsed by removing the
199             # compiled file too.
200             remove_files(TESTFN)
201
202             # Now damage the module.
203             f = open(source, "w")
204             print >> f, "a = 10"
205             print >> f, "b = 20//0"
206             f.close()
207
208             self.assertRaises(ZeroDivisionError, reload, mod)
209
210             # But we still expect the module to be in sys.modules.
211             mod = sys.modules.get(TESTFN)
212             self.failIf(mod is None, "expected module to still be in sys.modules")
213
214             # We should have replaced a w/ 10, but the old b value should
215             # stick.
216             self.assertEquals(mod.a, 10, "module has wrong attribute values")
217             self.assertEquals(mod.b, 2, "module has wrong attribute values")
218
219         finally:
220             sys.path.pop(0)
221             remove_files(TESTFN)
222             if TESTFN in sys.modules:
223                 del sys.modules[TESTFN]
224
225     def test_infinite_reload(self):
226         # Bug #742342 reports that Python segfaults (infinite recursion in C)
227         #  when faced with self-recursive reload()ing.
228
229         sys.path.insert(0, os.path.dirname(__file__))
230         try:
231             import infinite_reload
232         finally:
233             sys.path.pop(0)
234
235     def test_import_name_binding(self):
236         # import x.y.z binds x in the current namespace
237         import test as x
238         import test.test_support
239         self.assert_(x is test, x.__name__)
240         self.assert_(hasattr(test.test_support, "__file__"))
241
242         # import x.y.z as w binds z as w
243         import test.test_support as y
244         self.assert_(y is test.test_support, y.__name__)
245
246     def test_import_initless_directory_warning(self):
247         with warnings.catch_warnings():
248             # Just a random non-package directory we always expect to be
249             # somewhere in sys.path...
250             warnings.simplefilter('error', ImportWarning)
251             self.assertRaises(ImportWarning, __import__, "site-packages")
252
253     def test_importbyfilename(self):
254         path = os.path.abspath(TESTFN)
255         try:
256             __import__(path)
257         except ImportError, err:
258             self.assertEqual("Import by filename is not supported.",
259                               err.args[0])
260         else:
261             self.fail("import by path didn't raise an exception")
262
263
264 class TestPycRewriting(unittest.TestCase):
265     # Test that the `co_filename` attribute on code objects always points
266     # to the right file, even when various things happen (e.g. both the .py
267     # and the .pyc file are renamed).
268
269     module_name = "unlikely_module_name"
270     module_source = """
271 import sys
272 code_filename = sys._getframe().f_code.co_filename
273 module_filename = __file__
274 constant = 1
275 def func():
276     pass
277 func_filename = func.func_code.co_filename
278 """
279     dir_name = os.path.abspath(TESTFN)
280     file_name = os.path.join(dir_name, module_name) + os.extsep + "py"
281     compiled_name = file_name + ("c" if __debug__ else "o")
282
283     def setUp(self):
284         self.sys_path = sys.path[:]
285         self.orig_module = sys.modules.pop(self.module_name, None)
286         os.mkdir(self.dir_name)
287         with open(self.file_name, "w") as f:
288             f.write(self.module_source)
289         sys.path.insert(0, self.dir_name)
290
291     def tearDown(self):
292         sys.path[:] = self.sys_path
293         if self.orig_module is not None:
294             sys.modules[self.module_name] = self.orig_module
295         else:
296             del sys.modules[self.module_name]
297         for file_name in self.file_name, self.compiled_name:
298             if os.path.exists(file_name):
299                 os.remove(file_name)
300         if os.path.exists(self.dir_name):
301             shutil.rmtree(self.dir_name)
302
303     def import_module(self):
304         ns = globals()
305         __import__(self.module_name, ns, ns)
306         return sys.modules[self.module_name]
307
308     def test_basics(self):
309         mod = self.import_module()
310         self.assertEqual(mod.module_filename, self.file_name)
311         self.assertEqual(mod.code_filename, self.file_name)
312         self.assertEqual(mod.func_filename, self.file_name)
313         del sys.modules[self.module_name]
314         mod = self.import_module()
315         self.assertEqual(mod.module_filename, self.compiled_name)
316         self.assertEqual(mod.code_filename, self.file_name)
317         self.assertEqual(mod.func_filename, self.file_name)
318
319     def test_incorrect_code_name(self):
320         py_compile.compile(self.file_name, dfile="another_module.py")
321         mod = self.import_module()
322         self.assertEqual(mod.module_filename, self.compiled_name)
323         self.assertEqual(mod.code_filename, self.file_name)
324         self.assertEqual(mod.func_filename, self.file_name)
325
326     def test_module_without_source(self):
327         target = "another_module.py"
328         py_compile.compile(self.file_name, dfile=target)
329         os.remove(self.file_name)
330         mod = self.import_module()
331         self.assertEqual(mod.module_filename, self.compiled_name)
332         self.assertEqual(mod.code_filename, target)
333         self.assertEqual(mod.func_filename, target)
334
335     def test_foreign_code(self):
336         py_compile.compile(self.file_name)
337         with open(self.compiled_name, "rb") as f:
338             header = f.read(8)
339             code = marshal.load(f)
340         constants = list(code.co_consts)
341         foreign_code = test_main.func_code
342         pos = constants.index(1)
343         constants[pos] = foreign_code
344         code = type(code)(code.co_argcount, code.co_nlocals, code.co_stacksize,
345                           code.co_flags, code.co_code, tuple(constants),
346                           code.co_names, code.co_varnames, code.co_filename,
347                           code.co_name, code.co_firstlineno, code.co_lnotab,
348                           code.co_freevars, code.co_cellvars)
349         with open(self.compiled_name, "wb") as f:
350             f.write(header)
351             marshal.dump(code, f)
352         mod = self.import_module()
353         self.assertEqual(mod.constant.co_filename, foreign_code.co_filename)
354
355 class PathsTests(unittest.TestCase):
356     path = TESTFN
357
358     def setUp(self):
359         os.mkdir(self.path)
360         self.syspath = sys.path[:]
361
362     def tearDown(self):
363         shutil.rmtree(self.path)
364         sys.path = self.syspath
365
366     # http://bugs.python.org/issue1293
367     def test_trailing_slash(self):
368         f = open(os.path.join(self.path, 'test_trailing_slash.py'), 'w')
369         f.write("testdata = 'test_trailing_slash'")
370         f.close()
371         sys.path.append(self.path+'/')
372         mod = __import__("test_trailing_slash")
373         self.assertEqual(mod.testdata, 'test_trailing_slash')
374         unload("test_trailing_slash")
375
376 class RelativeImport(unittest.TestCase):
377     def tearDown(self):
378         try:
379             del sys.modules["test.relimport"]
380         except:
381             pass
382
383     def test_relimport_star(self):
384         # This will import * from .test_import.
385         from . import relimport
386         self.assertTrue(hasattr(relimport, "RelativeImport"))
387
388     def test_issue3221(self):
389         def check_absolute():
390             exec "from os import path" in ns
391         def check_relative():
392             exec "from . import relimport" in ns
393         # Check both OK with __package__ and __name__ correct
394         ns = dict(__package__='test', __name__='test.notarealmodule')
395         check_absolute()
396         check_relative()
397         # Check both OK with only __name__ wrong
398         ns = dict(__package__='test', __name__='notarealpkg.notarealmodule')
399         check_absolute()
400         check_relative()
401         # Check relative fails with only __package__ wrong
402         ns = dict(__package__='foo', __name__='test.notarealmodule')
403         with check_warnings() as w:
404             check_absolute()
405             self.assert_('foo' in str(w.message))
406             self.assertEqual(w.category, RuntimeWarning)
407         self.assertRaises(SystemError, check_relative)
408         # Check relative fails with __package__ and __name__ wrong
409         ns = dict(__package__='foo', __name__='notarealpkg.notarealmodule')
410         with check_warnings() as w:
411             check_absolute()
412             self.assert_('foo' in str(w.message))
413             self.assertEqual(w.category, RuntimeWarning)
414         self.assertRaises(SystemError, check_relative)
415         # Check both fail with package set to a non-string
416         ns = dict(__package__=object())
417         self.assertRaises(ValueError, check_absolute)
418         self.assertRaises(ValueError, check_relative)
419
420 def test_main(verbose=None):
421     run_unittest(ImportTest, TestPycRewriting, PathsTests, RelativeImport)
422
423 if __name__ == '__main__':
424     # test needs to be a package, so we can do relative import
425     from test.test_import import test_main
426     test_main()