blob: 44e67c37a09ec2c3b142009630f0371b5c4624c6 [file] [log] [blame]
Thomas Wouters89f507f2006-12-13 04:49:30 +00001import unittest
Tim Peters6d699ca2000-10-06 18:46:22 +00002import os
Alexandre Vassalotti9d58e3e2009-07-17 10:55:50 +00003import stat
Tim Peters6d699ca2000-10-06 18:46:22 +00004import random
Christian Heimes90333392007-11-01 19:08:42 +00005import shutil
Guido van Rossumbd6f4fb2000-10-24 17:16:32 +00006import sys
Neal Norwitz7fdcb412002-06-14 01:07:39 +00007import py_compile
Thomas Wouters902d6eb2007-01-09 23:18:33 +00008import warnings
Christian Heimes13a7a212008-01-07 17:13:09 +00009import imp
Antoine Pitroud35cbf62009-01-06 19:02:24 +000010import marshal
Alexandre Vassalotti9d58e3e2009-07-17 10:55:50 +000011from test.support import unlink, TESTFN, unload, run_unittest, TestFailed
Guido van Rossumbd6f4fb2000-10-24 17:16:32 +000012
Tim Peters72f98e92001-05-08 15:19:57 +000013
Tim Peters08138fd2004-08-02 03:58:27 +000014def remove_files(name):
Skip Montanaro7a98be22007-08-16 14:35:24 +000015 for f in (name + ".py",
16 name + ".pyc",
17 name + ".pyo",
18 name + ".pyw",
Tim Peters08138fd2004-08-02 03:58:27 +000019 name + "$py.class"):
20 if os.path.exists(f):
21 os.remove(f)
22
Tim Petersc1731372001-08-04 08:12:36 +000023
Thomas Wouters89f507f2006-12-13 04:49:30 +000024class ImportTest(unittest.TestCase):
Tim Petersc1731372001-08-04 08:12:36 +000025
Thomas Wouters89f507f2006-12-13 04:49:30 +000026 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.
Tim Petersc1731372001-08-04 08:12:36 +000029 try:
Thomas Wouters89f507f2006-12-13 04:49:30 +000030 import RAnDoM
31 except ImportError:
Tim Peters08138fd2004-08-02 03:58:27 +000032 pass
33 else:
Thomas Wouters89f507f2006-12-13 04:49:30 +000034 self.fail("import of RAnDoM should have failed (case mismatch)")
Tim Peters08138fd2004-08-02 03:58:27 +000035
Thomas Wouters89f507f2006-12-13 04:49:30 +000036 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
Tim Peters08138fd2004-08-02 03:58:27 +000039
Thomas Wouters89f507f2006-12-13 04:49:30 +000040 def testImport(self):
41 def test_with_extension(ext):
42 # ext normally ".py"; perhaps ".pyw"
43 source = TESTFN + ext
Skip Montanaro7a98be22007-08-16 14:35:24 +000044 pyo = TESTFN + ".pyo"
Thomas Wouters89f507f2006-12-13 04:49:30 +000045 if sys.platform.startswith('java'):
46 pyc = TESTFN + "$py.class"
47 else:
Skip Montanaro7a98be22007-08-16 14:35:24 +000048 pyc = TESTFN + ".pyc"
Tim Peters08138fd2004-08-02 03:58:27 +000049
Benjamin Peterson16a1f632009-06-13 13:01:19 +000050 with open(source, "w") as f:
51 print("# This tests Python's ability to import a", ext, "file.", file=f)
52 a = random.randrange(1000)
53 b = random.randrange(1000)
54 print("a =", a, file=f)
55 print("b =", b, file=f)
Jeremy Hylton3e0055f2005-10-20 19:59:25 +000056
Amaury Forgeot d'Arcdd9e3b82007-11-16 00:56:23 +000057 if TESTFN in sys.modules:
58 del sys.modules[TESTFN]
Thomas Wouters89f507f2006-12-13 04:49:30 +000059 try:
60 try:
61 mod = __import__(TESTFN)
Guido van Rossumb940e112007-01-10 16:19:56 +000062 except ImportError as err:
Thomas Wouters89f507f2006-12-13 04:49:30 +000063 self.fail("import from %s failed: %s" % (ext, err))
Jeremy Hylton3e0055f2005-10-20 19:59:25 +000064
Thomas Wouters89f507f2006-12-13 04:49:30 +000065 self.assertEquals(mod.a, a,
66 "module loaded (%s) but contents invalid" % mod)
67 self.assertEquals(mod.b, b,
68 "module loaded (%s) but contents invalid" % mod)
69 finally:
Guido van Rossume7ba4952007-06-06 23:52:48 +000070 unlink(source)
71 unlink(pyc)
72 unlink(pyo)
Thomas Wouters89f507f2006-12-13 04:49:30 +000073 del sys.modules[TESTFN]
Thomas Wouters477c8d52006-05-27 19:21:47 +000074
Thomas Wouters89f507f2006-12-13 04:49:30 +000075 sys.path.insert(0, os.curdir)
76 try:
Skip Montanaro7a98be22007-08-16 14:35:24 +000077 test_with_extension(".py")
Thomas Wouters89f507f2006-12-13 04:49:30 +000078 if sys.platform.startswith("win"):
79 for ext in ".PY", ".Py", ".pY", ".pyw", ".PYW", ".pYw":
80 test_with_extension(ext)
81 finally:
82 del sys.path[0]
Thomas Wouters477c8d52006-05-27 19:21:47 +000083
Alexandre Vassalotti9d58e3e2009-07-17 10:55:50 +000084 @unittest.skipUnless(os.name == 'posix', "test meaningful only on posix systems")
85 def test_execute_bit_not_copied(self):
86 # Issue 6070: under posix .pyc files got their execute bit set if
87 # the .py file had the execute bit set, but they aren't executable.
88 oldmask = os.umask(0o022)
89 sys.path.insert(0, os.curdir)
90 try:
91 fname = TESTFN + os.extsep + "py"
92 f = open(fname, 'w').close()
93 os.chmod(fname, (stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH |
94 stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH))
95 __import__(TESTFN)
96 fn = fname + 'c'
97 if not os.path.exists(fn):
98 fn = fname + 'o'
99 if not os.path.exists(fn): raise TestFailed("__import__ did "
100 "not result in creation of either a .pyc or .pyo file")
101 s = os.stat(fn)
102 self.assertEquals(stat.S_IMODE(s.st_mode),
103 stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH)
104 finally:
105 os.umask(oldmask)
106 remove_files(TESTFN)
107 if TESTFN in sys.modules: del sys.modules[TESTFN]
108 del sys.path[0]
109
Thomas Wouters89f507f2006-12-13 04:49:30 +0000110 def testImpModule(self):
111 # Verify that the imp module can correctly load and find .py files
112 import imp
113 x = imp.find_module("os")
114 os = imp.load_module("os", *x)
115
116 def test_module_with_large_stack(self, module='longlist'):
117 # create module w/list of 65000 elements to test bug #561858
Skip Montanaro7a98be22007-08-16 14:35:24 +0000118 filename = module + '.py'
Thomas Wouters89f507f2006-12-13 04:49:30 +0000119
120 # create a file with a list of 65000 elements
121 f = open(filename, 'w+')
122 f.write('d = [\n')
123 for i in range(65000):
124 f.write('"",\n')
125 f.write(']')
126 f.close()
127
128 # compile & remove .py file, we only need .pyc (or .pyo)
129 f = open(filename, 'r')
130 py_compile.compile(filename)
131 f.close()
132 os.unlink(filename)
133
134 # need to be able to load from current dir
135 sys.path.append('')
136
137 # this used to crash
138 exec('import ' + module)
139
140 # cleanup
141 del sys.path[-1]
Skip Montanaro7a98be22007-08-16 14:35:24 +0000142 for ext in '.pyc', '.pyo':
143 fname = module + ext
Thomas Wouters89f507f2006-12-13 04:49:30 +0000144 if os.path.exists(fname):
145 os.unlink(fname)
146
147 def test_failing_import_sticks(self):
Skip Montanaro7a98be22007-08-16 14:35:24 +0000148 source = TESTFN + ".py"
Thomas Wouters89f507f2006-12-13 04:49:30 +0000149 f = open(source, "w")
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000150 print("a = 1/0", file=f)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000151 f.close()
152
153 # New in 2.4, we shouldn't be able to import that no matter how often
154 # we try.
155 sys.path.insert(0, os.curdir)
Guido van Rossume7ba4952007-06-06 23:52:48 +0000156 if TESTFN in sys.modules:
157 del sys.modules[TESTFN]
Thomas Wouters89f507f2006-12-13 04:49:30 +0000158 try:
159 for i in 1, 2, 3:
160 try:
161 mod = __import__(TESTFN)
162 except ZeroDivisionError:
163 if TESTFN in sys.modules:
164 self.fail("damaged module in sys.modules on %i. try" % i)
165 else:
166 self.fail("was able to import a damaged module on %i. try" % i)
167 finally:
168 sys.path.pop(0)
169 remove_files(TESTFN)
170
Thomas Wouters89f507f2006-12-13 04:49:30 +0000171 def test_import_name_binding(self):
172 # import x.y.z binds x in the current namespace
173 import test as x
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000174 import test.support
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000175 self.assertTrue(x is test, x.__name__)
176 self.assertTrue(hasattr(test.support, "__file__"))
Thomas Wouters89f507f2006-12-13 04:49:30 +0000177
178 # import x.y.z as w binds z as w
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000179 import test.support as y
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000180 self.assertTrue(y is test.support, y.__name__)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000181
182 def test_import_initless_directory_warning(self):
Brett Cannon1cd02472008-09-09 01:52:27 +0000183 with warnings.catch_warnings():
Thomas Wouters89f507f2006-12-13 04:49:30 +0000184 # Just a random non-package directory we always expect to be
185 # somewhere in sys.path...
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000186 warnings.simplefilter('error', ImportWarning)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000187 self.assertRaises(ImportWarning, __import__, "site-packages")
Thomas Wouters89f507f2006-12-13 04:49:30 +0000188
Christian Heimes13a7a212008-01-07 17:13:09 +0000189 def test_failing_reload(self):
190 # A failing reload should leave the module object in sys.modules.
191 source = TESTFN + ".py"
192 with open(source, "w") as f:
193 f.write("a = 1\nb=2\n")
194
195 sys.path.insert(0, os.curdir)
196 try:
197 mod = __import__(TESTFN)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000198 self.assertTrue(TESTFN in sys.modules, "expected module in sys.modules")
Christian Heimes13a7a212008-01-07 17:13:09 +0000199 self.assertEquals(mod.a, 1, "module has wrong attribute values")
200 self.assertEquals(mod.b, 2, "module has wrong attribute values")
201
202 # On WinXP, just replacing the .py file wasn't enough to
203 # convince reload() to reparse it. Maybe the timestamp didn't
204 # move enough. We force it to get reparsed by removing the
205 # compiled file too.
206 remove_files(TESTFN)
207
208 # Now damage the module.
209 with open(source, "w") as f:
210 f.write("a = 10\nb=20//0\n")
211
212 self.assertRaises(ZeroDivisionError, imp.reload, mod)
213 # But we still expect the module to be in sys.modules.
214 mod = sys.modules.get(TESTFN)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000215 self.assertFalse(mod is None, "expected module to still be in sys.modules")
Christian Heimes13a7a212008-01-07 17:13:09 +0000216
217 # We should have replaced a w/ 10, but the old b value should
218 # stick.
219 self.assertEquals(mod.a, 10, "module has wrong attribute values")
220 self.assertEquals(mod.b, 2, "module has wrong attribute values")
221
222 finally:
223 sys.path.pop(0)
224 remove_files(TESTFN)
225 if TESTFN in sys.modules:
226 del sys.modules[TESTFN]
227
Christian Heimes3b06e532008-01-07 20:12:44 +0000228 def test_file_to_source(self):
229 # check if __file__ points to the source file where available
230 source = TESTFN + ".py"
231 with open(source, "w") as f:
232 f.write("test = None\n")
233
234 sys.path.insert(0, os.curdir)
235 try:
236 mod = __import__(TESTFN)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000237 self.assertTrue(mod.__file__.endswith('.py'))
Christian Heimes3b06e532008-01-07 20:12:44 +0000238 os.remove(source)
239 del sys.modules[TESTFN]
240 mod = __import__(TESTFN)
Christian Heimes3540b502008-01-11 07:03:05 +0000241 ext = mod.__file__[-4:]
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000242 self.assertTrue(ext in ('.pyc', '.pyo'), ext)
Christian Heimes3b06e532008-01-07 20:12:44 +0000243 finally:
244 sys.path.pop(0)
245 remove_files(TESTFN)
246 if TESTFN in sys.modules:
247 del sys.modules[TESTFN]
248
249
Christian Heimes454f37b2008-01-10 00:10:02 +0000250 def test_importbyfilename(self):
251 path = os.path.abspath(TESTFN)
252 try:
253 __import__(path)
254 except ImportError as err:
255 self.assertEqual("Import by filename is not supported.",
256 err.args[0])
257 else:
258 self.fail("import by path didn't raise an exception")
259
Alexandre Vassalotti9d58e3e2009-07-17 10:55:50 +0000260
Antoine Pitroud35cbf62009-01-06 19:02:24 +0000261class TestPycRewriting(unittest.TestCase):
262 # Test that the `co_filename` attribute on code objects always points
263 # to the right file, even when various things happen (e.g. both the .py
264 # and the .pyc file are renamed).
265
266 module_name = "unlikely_module_name"
267 module_source = """
268import sys
269code_filename = sys._getframe().f_code.co_filename
270module_filename = __file__
271constant = 1
272def func():
273 pass
274func_filename = func.__code__.co_filename
275"""
276 dir_name = os.path.abspath(TESTFN)
277 file_name = os.path.join(dir_name, module_name) + os.extsep + "py"
278 compiled_name = file_name + ("c" if __debug__ else "o")
279
280 def setUp(self):
281 self.sys_path = sys.path[:]
282 self.orig_module = sys.modules.pop(self.module_name, None)
283 os.mkdir(self.dir_name)
284 with open(self.file_name, "w") as f:
285 f.write(self.module_source)
286 sys.path.insert(0, self.dir_name)
287
288 def tearDown(self):
289 sys.path[:] = self.sys_path
290 if self.orig_module is not None:
291 sys.modules[self.module_name] = self.orig_module
292 else:
293 del sys.modules[self.module_name]
294 for file_name in self.file_name, self.compiled_name:
295 if os.path.exists(file_name):
296 os.remove(file_name)
297 if os.path.exists(self.dir_name):
298 shutil.rmtree(self.dir_name)
299
300 def import_module(self):
301 ns = globals()
302 __import__(self.module_name, ns, ns)
303 return sys.modules[self.module_name]
304
305 def test_basics(self):
306 mod = self.import_module()
307 self.assertEqual(mod.module_filename, self.file_name)
308 self.assertEqual(mod.code_filename, self.file_name)
309 self.assertEqual(mod.func_filename, self.file_name)
310 del sys.modules[self.module_name]
311 mod = self.import_module()
312 self.assertEqual(mod.module_filename, self.file_name)
313 self.assertEqual(mod.code_filename, self.file_name)
314 self.assertEqual(mod.func_filename, self.file_name)
315
316 def test_incorrect_code_name(self):
317 py_compile.compile(self.file_name, dfile="another_module.py")
318 mod = self.import_module()
319 self.assertEqual(mod.module_filename, self.file_name)
320 self.assertEqual(mod.code_filename, self.file_name)
321 self.assertEqual(mod.func_filename, self.file_name)
322
323 def test_module_without_source(self):
324 target = "another_module.py"
325 py_compile.compile(self.file_name, dfile=target)
326 os.remove(self.file_name)
327 mod = self.import_module()
328 self.assertEqual(mod.module_filename, self.compiled_name)
329 self.assertEqual(mod.code_filename, target)
330 self.assertEqual(mod.func_filename, target)
331
332 def test_foreign_code(self):
333 py_compile.compile(self.file_name)
334 with open(self.compiled_name, "rb") as f:
335 header = f.read(8)
336 code = marshal.load(f)
337 constants = list(code.co_consts)
338 foreign_code = test_main.__code__
339 pos = constants.index(1)
340 constants[pos] = foreign_code
341 code = type(code)(code.co_argcount, code.co_kwonlyargcount,
342 code.co_nlocals, code.co_stacksize,
343 code.co_flags, code.co_code, tuple(constants),
344 code.co_names, code.co_varnames, code.co_filename,
345 code.co_name, code.co_firstlineno, code.co_lnotab,
346 code.co_freevars, code.co_cellvars)
347 with open(self.compiled_name, "wb") as f:
348 f.write(header)
349 marshal.dump(code, f)
350 mod = self.import_module()
351 self.assertEqual(mod.constant.co_filename, foreign_code.co_filename)
352
Christian Heimes204093a2007-11-01 22:37:07 +0000353class PathsTests(unittest.TestCase):
354 SAMPLES = ('test', 'test\u00e4\u00f6\u00fc\u00df', 'test\u00e9\u00e8',
355 'test\u00b0\u00b3\u00b2')
Christian Heimes90333392007-11-01 19:08:42 +0000356 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
Christian Heimes1d1a4002007-11-01 19:41:07 +0000366 # 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
Kristján Valur Jónssond9aab512009-01-24 10:50:45 +0000376 # http://bugs.python.org/issue3677
377 def _test_UNC_path(self):
378 f = open(os.path.join(self.path, 'test_trailing_slash.py'), 'w')
379 f.write("testdata = 'test_trailing_slash'")
380 f.close()
381 #create the UNC path, like \\myhost\c$\foo\bar
382 path = os.path.abspath(self.path)
383 import socket
384 hn = socket.gethostname()
385 drive = path[0]
386 unc = "\\\\%s\\%s$"%(hn, drive)
387 unc += path[2:]
388 sys.path.append(path)
389 mod = __import__("test_trailing_slash")
390 self.assertEqual(mod.testdata, 'test_trailing_slash')
391 unload("test_trailing_slash")
392
393 if sys.platform == "win32":
394 test_UNC_path = _test_UNC_path
395
396
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000397class RelativeImport(unittest.TestCase):
398 def tearDown(self):
399 try:
400 del sys.modules["test.relimport"]
401 except:
402 pass
403
404 def test_relimport_star(self):
405 # This will import * from .test_import.
406 from . import relimport
407 self.assertTrue(hasattr(relimport, "RelativeImport"))
408
Georg Brandl2ee470f2008-07-16 12:55:28 +0000409 def test_issue3221(self):
Benjamin Petersonfcf5d632008-10-16 23:24:44 +0000410 # Note for mergers: the 'absolute' tests from the 2.x branch
411 # are missing in Py3k because implicit relative imports are
412 # a thing of the past
Georg Brandl2ee470f2008-07-16 12:55:28 +0000413 def check_relative():
414 exec("from . import relimport", ns)
Benjamin Petersonfcf5d632008-10-16 23:24:44 +0000415 # Check relative import OK with __package__ and __name__ correct
Georg Brandl2ee470f2008-07-16 12:55:28 +0000416 ns = dict(__package__='test', __name__='test.notarealmodule')
417 check_relative()
Benjamin Petersonfcf5d632008-10-16 23:24:44 +0000418 # Check relative import OK with only __name__ wrong
Georg Brandl2ee470f2008-07-16 12:55:28 +0000419 ns = dict(__package__='test', __name__='notarealpkg.notarealmodule')
420 check_relative()
Benjamin Petersonfcf5d632008-10-16 23:24:44 +0000421 # Check relative import fails with only __package__ wrong
Georg Brandl2ee470f2008-07-16 12:55:28 +0000422 ns = dict(__package__='foo', __name__='test.notarealmodule')
423 self.assertRaises(SystemError, check_relative)
Benjamin Petersonfcf5d632008-10-16 23:24:44 +0000424 # Check relative import fails with __package__ and __name__ wrong
Georg Brandl2ee470f2008-07-16 12:55:28 +0000425 ns = dict(__package__='foo', __name__='notarealpkg.notarealmodule')
426 self.assertRaises(SystemError, check_relative)
Benjamin Petersonfcf5d632008-10-16 23:24:44 +0000427 # Check relative import fails with package set to a non-string
Georg Brandl2ee470f2008-07-16 12:55:28 +0000428 ns = dict(__package__=object())
429 self.assertRaises(ValueError, check_relative)
430
Thomas Wouters89f507f2006-12-13 04:49:30 +0000431def test_main(verbose=None):
Antoine Pitroud35cbf62009-01-06 19:02:24 +0000432 run_unittest(ImportTest, TestPycRewriting, PathsTests, RelativeImport)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000433
434if __name__ == '__main__':
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000435 # test needs to be a package, so we can do relative import
436 from test.test_import import test_main
Thomas Wouters89f507f2006-12-13 04:49:30 +0000437 test_main()