1 # Test the runpy module
8 from test
.test_support
import verbose
, run_unittest
, forget
9 from test
.script_helper
import (temp_dir
, make_script
, compile_script
,
10 make_pkg
, make_zip_script
, make_zip_pkg
)
13 from runpy
import _run_code
, _run_module_code
, run_module
, run_path
14 # Note: This module can't safely test _run_module_as_main as it
15 # runs its tests in the current process, which would mess with the
16 # real __main__ module (usually test.regrtest)
17 # See test_cmd_line_script for a test that executes that code path
19 # Set up the test code and expected results
21 class RunModuleCodeTest(unittest
.TestCase
):
22 """Unit tests for runpy._run_code and runpy._run_module_code"""
24 expected_result
= ["Top level assignment", "Lower level reference"]
26 "# Check basic code execution\n"
27 "result = ['Top level assignment']\n"
29 " result.append('Lower level reference')\n"
31 "# Check the sys module\n"
33 "run_argv0 = sys.argv[0]\n"
34 "run_name_in_sys_modules = __name__ in sys.modules\n"
35 "if run_name_in_sys_modules:\n"
36 " module_in_sys_modules = globals() is sys.modules[__name__].__dict__\n"
37 "# Check nested operation\n"
39 "nested = runpy._run_module_code('x=1\\n', mod_name='<run>')\n"
42 def test_run_code(self
):
43 saved_argv0
= sys
.argv
[0]
44 d
= _run_code(self
.test_source
, {})
45 self
.assertEqual(d
["result"], self
.expected_result
)
46 self
.assertIs(d
["__name__"], None)
47 self
.assertIs(d
["__file__"], None)
48 self
.assertIs(d
["__loader__"], None)
49 self
.assertIs(d
["__package__"], None)
50 self
.assertIs(d
["run_argv0"], saved_argv0
)
51 self
.assertNotIn("run_name", d
)
52 self
.assertIs(sys
.argv
[0], saved_argv0
)
54 def test_run_module_code(self
):
57 file = "Some other nonsense"
58 loader
= "Now you're just being silly"
59 package
= '' # Treat as a top level module
60 d1
= dict(initial
=initial
)
61 saved_argv0
= sys
.argv
[0]
62 d2
= _run_module_code(self
.test_source
,
68 self
.assertNotIn("result", d1
)
69 self
.assertIs(d2
["initial"], initial
)
70 self
.assertEqual(d2
["result"], self
.expected_result
)
71 self
.assertEqual(d2
["nested"]["x"], 1)
72 self
.assertIs(d2
["__name__"], name
)
73 self
.assertTrue(d2
["run_name_in_sys_modules"])
74 self
.assertTrue(d2
["module_in_sys_modules"])
75 self
.assertIs(d2
["__file__"], file)
76 self
.assertIs(d2
["run_argv0"], file)
77 self
.assertIs(d2
["__loader__"], loader
)
78 self
.assertIs(d2
["__package__"], package
)
79 self
.assertIs(sys
.argv
[0], saved_argv0
)
80 self
.assertNotIn(name
, sys
.modules
)
83 class RunModuleTest(unittest
.TestCase
):
84 """Unit tests for runpy.run_module"""
86 def expect_import_error(self
, mod_name
):
92 self
.fail("Expected import error for " + mod_name
)
94 def test_invalid_names(self
):
96 self
.expect_import_error("sys")
97 # Non-existent modules
98 self
.expect_import_error("sys.imp.eric")
99 self
.expect_import_error("os.path.half")
100 self
.expect_import_error("a.bee")
101 self
.expect_import_error(".howard")
102 self
.expect_import_error("..eaten")
103 # Package without __main__.py
104 self
.expect_import_error("multiprocessing")
106 def test_library_module(self
):
109 def _add_pkg_dir(self
, pkg_dir
):
111 pkg_fname
= os
.path
.join(pkg_dir
, "__init__"+os
.extsep
+"py")
112 pkg_file
= open(pkg_fname
, "w")
116 def _make_pkg(self
, source
, depth
, mod_base
="runpy_test"):
117 pkg_name
= "__runpy_pkg__"
118 test_fname
= mod_base
+os
.extsep
+"py"
119 pkg_dir
= sub_dir
= tempfile
.mkdtemp()
120 if verbose
: print " Package tree in:", sub_dir
121 sys
.path
.insert(0, pkg_dir
)
122 if verbose
: print " Updated sys.path:", sys
.path
[0]
123 for i
in range(depth
):
124 sub_dir
= os
.path
.join(sub_dir
, pkg_name
)
125 pkg_fname
= self
._add
_pkg
_dir
(sub_dir
)
126 if verbose
: print " Next level in:", sub_dir
127 if verbose
: print " Created:", pkg_fname
128 mod_fname
= os
.path
.join(sub_dir
, test_fname
)
129 mod_file
= open(mod_fname
, "w")
130 mod_file
.write(source
)
132 if verbose
: print " Created:", mod_fname
133 mod_name
= (pkg_name
+".")*depth
+ mod_base
134 return pkg_dir
, mod_fname
, mod_name
136 def _del_pkg(self
, top
, depth
, mod_name
):
137 for entry
in list(sys
.modules
):
138 if entry
.startswith("__runpy_pkg__"):
139 del sys
.modules
[entry
]
140 if verbose
: print " Removed sys.modules entries"
142 if verbose
: print " Removed sys.path entry"
143 for root
, dirs
, files
in os
.walk(top
, topdown
=False):
146 os
.remove(os
.path
.join(root
, name
))
148 if verbose
: print ex
# Persist with cleaning up
150 fullname
= os
.path
.join(root
, name
)
154 if verbose
: print ex
# Persist with cleaning up
157 if verbose
: print " Removed package tree"
159 if verbose
: print ex
# Persist with cleaning up
161 def _check_module(self
, depth
):
162 pkg_dir
, mod_fname
, mod_name
= (
163 self
._make
_pkg
("x=1\n", depth
))
166 if verbose
: print "Running from source:", mod_name
167 d1
= run_module(mod_name
) # Read from source
168 self
.assertIn("x", d1
)
169 self
.assertTrue(d1
["x"] == 1)
170 del d1
# Ensure __loader__ entry doesn't keep file open
173 if verbose
: print "Running from compiled:", mod_name
174 d2
= run_module(mod_name
) # Read from bytecode
175 self
.assertIn("x", d2
)
176 self
.assertTrue(d2
["x"] == 1)
177 del d2
# Ensure __loader__ entry doesn't keep file open
179 self
._del
_pkg
(pkg_dir
, depth
, mod_name
)
180 if verbose
: print "Module executed successfully"
182 def _check_package(self
, depth
):
183 pkg_dir
, mod_fname
, mod_name
= (
184 self
._make
_pkg
("x=1\n", depth
, "__main__"))
185 pkg_name
, _
, _
= mod_name
.rpartition(".")
188 if verbose
: print "Running from source:", pkg_name
189 d1
= run_module(pkg_name
) # Read from source
190 self
.assertIn("x", d1
)
191 self
.assertTrue(d1
["x"] == 1)
192 del d1
# Ensure __loader__ entry doesn't keep file open
195 if verbose
: print "Running from compiled:", pkg_name
196 d2
= run_module(pkg_name
) # Read from bytecode
197 self
.assertIn("x", d2
)
198 self
.assertTrue(d2
["x"] == 1)
199 del d2
# Ensure __loader__ entry doesn't keep file open
201 self
._del
_pkg
(pkg_dir
, depth
, pkg_name
)
202 if verbose
: print "Package executed successfully"
204 def _add_relative_modules(self
, base_dir
, source
, depth
):
206 raise ValueError("Relative module test needs depth > 1")
207 pkg_name
= "__runpy_pkg__"
208 module_dir
= base_dir
209 for i
in range(depth
):
210 parent_dir
= module_dir
211 module_dir
= os
.path
.join(module_dir
, pkg_name
)
213 sibling_fname
= os
.path
.join(module_dir
, "sibling"+os
.extsep
+"py")
214 sibling_file
= open(sibling_fname
, "w")
216 if verbose
: print " Added sibling module:", sibling_fname
218 uncle_dir
= os
.path
.join(parent_dir
, "uncle")
219 self
._add
_pkg
_dir
(uncle_dir
)
220 if verbose
: print " Added uncle package:", uncle_dir
221 cousin_dir
= os
.path
.join(uncle_dir
, "cousin")
222 self
._add
_pkg
_dir
(cousin_dir
)
223 if verbose
: print " Added cousin package:", cousin_dir
224 nephew_fname
= os
.path
.join(cousin_dir
, "nephew"+os
.extsep
+"py")
225 nephew_file
= open(nephew_fname
, "w")
227 if verbose
: print " Added nephew module:", nephew_fname
229 def _check_relative_imports(self
, depth
, run_name
=None):
231 from __future__ import absolute_import
232 from . import sibling
233 from ..uncle.cousin import nephew
235 pkg_dir
, mod_fname
, mod_name
= (
236 self
._make
_pkg
(contents
, depth
))
238 self
._add
_relative
_modules
(pkg_dir
, contents
, depth
)
239 pkg_name
= mod_name
.rpartition('.')[0]
240 if verbose
: print "Running from source:", mod_name
241 d1
= run_module(mod_name
, run_name
=run_name
) # Read from source
242 self
.assertIn("__package__", d1
)
243 self
.assertTrue(d1
["__package__"] == pkg_name
)
244 self
.assertIn("sibling", d1
)
245 self
.assertIn("nephew", d1
)
246 del d1
# Ensure __loader__ entry doesn't keep file open
249 if verbose
: print "Running from compiled:", mod_name
250 d2
= run_module(mod_name
, run_name
=run_name
) # Read from bytecode
251 self
.assertIn("__package__", d2
)
252 self
.assertTrue(d2
["__package__"] == pkg_name
)
253 self
.assertIn("sibling", d2
)
254 self
.assertIn("nephew", d2
)
255 del d2
# Ensure __loader__ entry doesn't keep file open
257 self
._del
_pkg
(pkg_dir
, depth
, mod_name
)
258 if verbose
: print "Module executed successfully"
260 def test_run_module(self
):
261 for depth
in range(4):
262 if verbose
: print "Testing package depth:", depth
263 self
._check
_module
(depth
)
265 def test_run_package(self
):
266 for depth
in range(1, 4):
267 if verbose
: print "Testing package depth:", depth
268 self
._check
_package
(depth
)
270 def test_explicit_relative_import(self
):
271 for depth
in range(2, 5):
272 if verbose
: print "Testing relative imports at depth:", depth
273 self
._check
_relative
_imports
(depth
)
275 def test_main_relative_import(self
):
276 for depth
in range(2, 5):
277 if verbose
: print "Testing main relative imports at depth:", depth
278 self
._check
_relative
_imports
(depth
, "__main__")
281 class RunPathTest(unittest
.TestCase
):
282 """Unit tests for runpy.run_path"""
283 # Based on corresponding tests in test_cmd_line_script
286 # Script may be run with optimisation enabled, so don't rely on assert
287 # statements being executed
288 def assertEqual(lhs, rhs):
290 raise AssertionError('%r != %r' % (lhs, rhs))
291 def assertIs(lhs, rhs):
293 raise AssertionError('%r is not %r' % (lhs, rhs))
294 # Check basic code execution
295 result = ['Top level assignment']
297 result.append('Lower level reference')
299 assertEqual(result, ['Top level assignment', 'Lower level reference'])
300 # Check the sys module
302 assertIs(globals(), sys.modules[__name__].__dict__)
306 def _make_test_script(self
, script_dir
, script_basename
, source
=None):
308 source
= self
.test_source
309 return make_script(script_dir
, script_basename
, source
)
311 def _check_script(self
, script_name
, expected_name
, expected_file
,
312 expected_argv0
, expected_package
):
313 result
= run_path(script_name
)
314 self
.assertEqual(result
["__name__"], expected_name
)
315 self
.assertEqual(result
["__file__"], expected_file
)
316 self
.assertIn("argv0", result
)
317 self
.assertEqual(result
["argv0"], expected_argv0
)
318 self
.assertEqual(result
["__package__"], expected_package
)
320 def _check_import_error(self
, script_name
, msg
):
322 self
.assertRaisesRegexp(ImportError, msg
, run_path
, script_name
)
324 def test_basic_script(self
):
325 with
temp_dir() as script_dir
:
327 script_name
= self
._make
_test
_script
(script_dir
, mod_name
)
328 self
._check
_script
(script_name
, "<run_path>", script_name
,
331 def test_script_compiled(self
):
332 with
temp_dir() as script_dir
:
334 script_name
= self
._make
_test
_script
(script_dir
, mod_name
)
335 compiled_name
= compile_script(script_name
)
336 os
.remove(script_name
)
337 self
._check
_script
(compiled_name
, "<run_path>", compiled_name
,
340 def test_directory(self
):
341 with
temp_dir() as script_dir
:
342 mod_name
= '__main__'
343 script_name
= self
._make
_test
_script
(script_dir
, mod_name
)
344 self
._check
_script
(script_dir
, "<run_path>", script_name
,
347 def test_directory_compiled(self
):
348 with
temp_dir() as script_dir
:
349 mod_name
= '__main__'
350 script_name
= self
._make
_test
_script
(script_dir
, mod_name
)
351 compiled_name
= compile_script(script_name
)
352 os
.remove(script_name
)
353 self
._check
_script
(script_dir
, "<run_path>", compiled_name
,
356 def test_directory_error(self
):
357 with
temp_dir() as script_dir
:
358 mod_name
= 'not_main'
359 script_name
= self
._make
_test
_script
(script_dir
, mod_name
)
360 msg
= "can't find '__main__' module in %r" % script_dir
361 self
._check
_import
_error
(script_dir
, msg
)
363 def test_zipfile(self
):
364 with
temp_dir() as script_dir
:
365 mod_name
= '__main__'
366 script_name
= self
._make
_test
_script
(script_dir
, mod_name
)
367 zip_name
, fname
= make_zip_script(script_dir
, 'test_zip', script_name
)
368 self
._check
_script
(zip_name
, "<run_path>", fname
, zip_name
, '')
370 def test_zipfile_compiled(self
):
371 with
temp_dir() as script_dir
:
372 mod_name
= '__main__'
373 script_name
= self
._make
_test
_script
(script_dir
, mod_name
)
374 compiled_name
= compile_script(script_name
)
375 zip_name
, fname
= make_zip_script(script_dir
, 'test_zip', compiled_name
)
376 self
._check
_script
(zip_name
, "<run_path>", fname
, zip_name
, '')
378 def test_zipfile_error(self
):
379 with
temp_dir() as script_dir
:
380 mod_name
= 'not_main'
381 script_name
= self
._make
_test
_script
(script_dir
, mod_name
)
382 zip_name
, fname
= make_zip_script(script_dir
, 'test_zip', script_name
)
383 msg
= "can't find '__main__' module in %r" % zip_name
384 self
._check
_import
_error
(zip_name
, msg
)
386 def test_main_recursion_error(self
):
387 with
temp_dir() as script_dir
, temp_dir() as dummy_dir
:
388 mod_name
= '__main__'
389 source
= ("import runpy\n"
390 "runpy.run_path(%r)\n") % dummy_dir
391 script_name
= self
._make
_test
_script
(script_dir
, mod_name
, source
)
392 zip_name
, fname
= make_zip_script(script_dir
, 'test_zip', script_name
)
393 msg
= "recursion depth exceeded"
394 self
.assertRaisesRegexp(RuntimeError, msg
, run_path
, zip_name
)
399 run_unittest(RunModuleCodeTest
, RunModuleTest
, RunPathTest
)
401 if __name__
== "__main__":