|
1 # Test the runpy module |
|
2 import unittest |
|
3 import os |
|
4 import os.path |
|
5 import sys |
|
6 import tempfile |
|
7 from test.test_support import verbose, run_unittest |
|
8 from runpy import _run_module_code, run_module |
|
9 |
|
10 # Set up the test code and expected results |
|
11 |
|
12 class RunModuleCodeTest(unittest.TestCase): |
|
13 |
|
14 expected_result = ["Top level assignment", "Lower level reference"] |
|
15 test_source = ( |
|
16 "# Check basic code execution\n" |
|
17 "result = ['Top level assignment']\n" |
|
18 "def f():\n" |
|
19 " result.append('Lower level reference')\n" |
|
20 "f()\n" |
|
21 "# Check the sys module\n" |
|
22 "import sys\n" |
|
23 "run_argv0 = sys.argv[0]\n" |
|
24 "if __name__ in sys.modules:\n" |
|
25 " run_name = sys.modules[__name__].__name__\n" |
|
26 "# Check nested operation\n" |
|
27 "import runpy\n" |
|
28 "nested = runpy._run_module_code('x=1\\n', mod_name='<run>',\n" |
|
29 " alter_sys=True)\n" |
|
30 ) |
|
31 |
|
32 |
|
33 def test_run_module_code(self): |
|
34 initial = object() |
|
35 name = "<Nonsense>" |
|
36 file = "Some other nonsense" |
|
37 loader = "Now you're just being silly" |
|
38 d1 = dict(initial=initial) |
|
39 saved_argv0 = sys.argv[0] |
|
40 d2 = _run_module_code(self.test_source, |
|
41 d1, |
|
42 name, |
|
43 file, |
|
44 loader, |
|
45 True) |
|
46 self.failUnless("result" not in d1) |
|
47 self.failUnless(d2["initial"] is initial) |
|
48 self.failUnless(d2["result"] == self.expected_result) |
|
49 self.failUnless(d2["nested"]["x"] == 1) |
|
50 self.failUnless(d2["__name__"] is name) |
|
51 self.failUnless(d2["run_name"] is name) |
|
52 self.failUnless(d2["__file__"] is file) |
|
53 self.failUnless(d2["run_argv0"] is file) |
|
54 self.failUnless(d2["__loader__"] is loader) |
|
55 self.failUnless(sys.argv[0] is saved_argv0) |
|
56 self.failUnless(name not in sys.modules) |
|
57 |
|
58 def test_run_module_code_defaults(self): |
|
59 saved_argv0 = sys.argv[0] |
|
60 d = _run_module_code(self.test_source) |
|
61 self.failUnless(d["result"] == self.expected_result) |
|
62 self.failUnless(d["__name__"] is None) |
|
63 self.failUnless(d["__file__"] is None) |
|
64 self.failUnless(d["__loader__"] is None) |
|
65 self.failUnless(d["run_argv0"] is saved_argv0) |
|
66 self.failUnless("run_name" not in d) |
|
67 self.failUnless(sys.argv[0] is saved_argv0) |
|
68 |
|
69 class RunModuleTest(unittest.TestCase): |
|
70 |
|
71 def expect_import_error(self, mod_name): |
|
72 try: |
|
73 run_module(mod_name) |
|
74 except ImportError: |
|
75 pass |
|
76 else: |
|
77 self.fail("Expected import error for " + mod_name) |
|
78 |
|
79 def test_invalid_names(self): |
|
80 self.expect_import_error("sys") |
|
81 self.expect_import_error("sys.imp.eric") |
|
82 self.expect_import_error("os.path.half") |
|
83 self.expect_import_error("a.bee") |
|
84 self.expect_import_error(".howard") |
|
85 self.expect_import_error("..eaten") |
|
86 |
|
87 def test_library_module(self): |
|
88 run_module("runpy") |
|
89 |
|
90 def _make_pkg(self, source, depth): |
|
91 pkg_name = "__runpy_pkg__" |
|
92 init_fname = "__init__"+os.extsep+"py" |
|
93 test_fname = "runpy_test"+os.extsep+"py" |
|
94 pkg_dir = sub_dir = tempfile.mkdtemp() |
|
95 if verbose: print " Package tree in:", sub_dir |
|
96 sys.path.insert(0, pkg_dir) |
|
97 if verbose: print " Updated sys.path:", sys.path[0] |
|
98 for i in range(depth): |
|
99 sub_dir = os.path.join(sub_dir, pkg_name) |
|
100 os.mkdir(sub_dir) |
|
101 if verbose: print " Next level in:", sub_dir |
|
102 pkg_fname = os.path.join(sub_dir, init_fname) |
|
103 pkg_file = open(pkg_fname, "w") |
|
104 pkg_file.close() |
|
105 if verbose: print " Created:", pkg_fname |
|
106 mod_fname = os.path.join(sub_dir, test_fname) |
|
107 mod_file = open(mod_fname, "w") |
|
108 mod_file.write(source) |
|
109 mod_file.close() |
|
110 if verbose: print " Created:", mod_fname |
|
111 mod_name = (pkg_name+".")*depth + "runpy_test" |
|
112 return pkg_dir, mod_fname, mod_name |
|
113 |
|
114 def _del_pkg(self, top, depth, mod_name): |
|
115 for i in range(depth+1): # Don't forget the module itself |
|
116 parts = mod_name.rsplit(".", i) |
|
117 entry = parts[0] |
|
118 try: |
|
119 del sys.modules[entry] |
|
120 except KeyError, ex: |
|
121 if verbose: print ex # Persist with cleaning up |
|
122 if verbose: print " Removed sys.modules entries" |
|
123 del sys.path[0] |
|
124 if verbose: print " Removed sys.path entry" |
|
125 for root, dirs, files in os.walk(top, topdown=False): |
|
126 for name in files: |
|
127 try: |
|
128 os.remove(os.path.join(root, name)) |
|
129 except OSError, ex: |
|
130 if verbose: print ex # Persist with cleaning up |
|
131 for name in dirs: |
|
132 fullname = os.path.join(root, name) |
|
133 try: |
|
134 os.rmdir(fullname) |
|
135 except OSError, ex: |
|
136 if verbose: print ex # Persist with cleaning up |
|
137 try: |
|
138 os.rmdir(top) |
|
139 if verbose: print " Removed package tree" |
|
140 except OSError, ex: |
|
141 if verbose: print ex # Persist with cleaning up |
|
142 |
|
143 def _check_module(self, depth): |
|
144 pkg_dir, mod_fname, mod_name = ( |
|
145 self._make_pkg("x=1\n", depth)) |
|
146 try: |
|
147 if verbose: print "Running from source:", mod_name |
|
148 d1 = run_module(mod_name) # Read from source |
|
149 self.failUnless(d1["x"] == 1) |
|
150 del d1 # Ensure __loader__ entry doesn't keep file open |
|
151 __import__(mod_name) |
|
152 os.remove(mod_fname) |
|
153 if verbose: print "Running from compiled:", mod_name |
|
154 d2 = run_module(mod_name) # Read from bytecode |
|
155 self.failUnless(d2["x"] == 1) |
|
156 del d2 # Ensure __loader__ entry doesn't keep file open |
|
157 finally: |
|
158 self._del_pkg(pkg_dir, depth, mod_name) |
|
159 if verbose: print "Module executed successfully" |
|
160 |
|
161 def test_run_module(self): |
|
162 for depth in range(4): |
|
163 if verbose: print "Testing package depth:", depth |
|
164 self._check_module(depth) |
|
165 |
|
166 |
|
167 def test_main(): |
|
168 run_unittest(RunModuleCodeTest) |
|
169 run_unittest(RunModuleTest) |
|
170 |
|
171 if __name__ == "__main__": |
|
172 test_main() |