~ubuntu-branches/ubuntu/maverick/python3.1/maverick

« back to all changes in this revision

Viewing changes to Lib/test/test_runpy.py

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2009-03-23 00:01:27 UTC
  • Revision ID: james.westby@ubuntu.com-20090323000127-5fstfxju4ufrhthq
Tags: upstream-3.1~a1+20090322
ImportĀ upstreamĀ versionĀ 3.1~a1+20090322

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Test the runpy module
 
2
import unittest
 
3
import os
 
4
import os.path
 
5
import sys
 
6
import tempfile
 
7
from test.support import verbose, run_unittest, forget
 
8
from runpy import _run_code, _run_module_code, run_module
 
9
 
 
10
# Note: This module can't safely test _run_module_as_main as it
 
11
# runs its tests in the current process, which would mess with the
 
12
# real __main__ module (usually test.regrtest)
 
13
# See test_cmd_line_script for a test that executes that code path
 
14
 
 
15
# Set up the test code and expected results
 
16
 
 
17
class RunModuleCodeTest(unittest.TestCase):
 
18
 
 
19
    expected_result = ["Top level assignment", "Lower level reference"]
 
20
    test_source = (
 
21
        "# Check basic code execution\n"
 
22
        "result = ['Top level assignment']\n"
 
23
        "def f():\n"
 
24
        "    result.append('Lower level reference')\n"
 
25
        "f()\n"
 
26
        "# Check the sys module\n"
 
27
        "import sys\n"
 
28
        "run_argv0 = sys.argv[0]\n"
 
29
        "run_name_in_sys_modules = __name__ in sys.modules\n"
 
30
        "if run_name_in_sys_modules:\n"
 
31
        "   module_in_sys_modules = globals() is sys.modules[__name__].__dict__\n"
 
32
        "# Check nested operation\n"
 
33
        "import runpy\n"
 
34
        "nested = runpy._run_module_code('x=1\\n', mod_name='<run>')\n"
 
35
    )
 
36
 
 
37
    def test_run_code(self):
 
38
        saved_argv0 = sys.argv[0]
 
39
        d = _run_code(self.test_source, {})
 
40
        self.failUnless(d["result"] == self.expected_result)
 
41
        self.failUnless(d["__name__"] is None)
 
42
        self.failUnless(d["__file__"] is None)
 
43
        self.failUnless(d["__loader__"] is None)
 
44
        self.failUnless(d["__package__"] is None)
 
45
        self.failUnless(d["run_argv0"] is saved_argv0)
 
46
        self.failUnless("run_name" not in d)
 
47
        self.failUnless(sys.argv[0] is saved_argv0)
 
48
 
 
49
    def test_run_module_code(self):
 
50
        initial = object()
 
51
        name = "<Nonsense>"
 
52
        file = "Some other nonsense"
 
53
        loader = "Now you're just being silly"
 
54
        package = '' # Treat as a top level module
 
55
        d1 = dict(initial=initial)
 
56
        saved_argv0 = sys.argv[0]
 
57
        d2 = _run_module_code(self.test_source,
 
58
                              d1,
 
59
                              name,
 
60
                              file,
 
61
                              loader,
 
62
                              package)
 
63
        self.failUnless("result" not in d1)
 
64
        self.failUnless(d2["initial"] is initial)
 
65
        self.assertEqual(d2["result"], self.expected_result)
 
66
        self.assertEqual(d2["nested"]["x"], 1)
 
67
        self.failUnless(d2["__name__"] is name)
 
68
        self.failUnless(d2["run_name_in_sys_modules"])
 
69
        self.failUnless(d2["module_in_sys_modules"])
 
70
        self.failUnless(d2["__file__"] is file)
 
71
        self.failUnless(d2["run_argv0"] is file)
 
72
        self.failUnless(d2["__loader__"] is loader)
 
73
        self.failUnless(d2["__package__"] is package)
 
74
        self.failUnless(sys.argv[0] is saved_argv0)
 
75
        self.failUnless(name not in sys.modules)
 
76
 
 
77
 
 
78
class RunModuleTest(unittest.TestCase):
 
79
 
 
80
    def expect_import_error(self, mod_name):
 
81
        try:
 
82
            run_module(mod_name)
 
83
        except ImportError:
 
84
            pass
 
85
        else:
 
86
            self.fail("Expected import error for " + mod_name)
 
87
 
 
88
    def test_invalid_names(self):
 
89
        # Builtin module
 
90
        self.expect_import_error("sys")
 
91
        # Non-existent modules
 
92
        self.expect_import_error("sys.imp.eric")
 
93
        self.expect_import_error("os.path.half")
 
94
        self.expect_import_error("a.bee")
 
95
        self.expect_import_error(".howard")
 
96
        self.expect_import_error("..eaten")
 
97
        # Package
 
98
        self.expect_import_error("logging")
 
99
 
 
100
    def test_library_module(self):
 
101
        run_module("runpy")
 
102
 
 
103
    def _add_pkg_dir(self, pkg_dir):
 
104
        os.mkdir(pkg_dir)
 
105
        pkg_fname = os.path.join(pkg_dir, "__init__.py")
 
106
        pkg_file = open(pkg_fname, "w")
 
107
        pkg_file.close()
 
108
        return pkg_fname
 
109
 
 
110
    def _make_pkg(self, source, depth):
 
111
        pkg_name = "__runpy_pkg__"
 
112
        test_fname = "runpy_test.py"
 
113
        pkg_dir = sub_dir = tempfile.mkdtemp()
 
114
        if verbose: print("  Package tree in:", sub_dir)
 
115
        sys.path.insert(0, pkg_dir)
 
116
        if verbose: print("  Updated sys.path:", sys.path[0])
 
117
        for i in range(depth):
 
118
            sub_dir = os.path.join(sub_dir, pkg_name)
 
119
            pkg_fname = self._add_pkg_dir(sub_dir)
 
120
            if verbose: print("  Next level in:", sub_dir)
 
121
            if verbose: print("  Created:", pkg_fname)
 
122
        mod_fname = os.path.join(sub_dir, test_fname)
 
123
        mod_file = open(mod_fname, "w")
 
124
        mod_file.write(source)
 
125
        mod_file.close()
 
126
        if verbose: print("  Created:", mod_fname)
 
127
        mod_name = (pkg_name+".")*depth + "runpy_test"
 
128
        return pkg_dir, mod_fname, mod_name
 
129
 
 
130
    def _del_pkg(self, top, depth, mod_name):
 
131
        for entry in list(sys.modules):
 
132
            if entry.startswith("__runpy_pkg__"):
 
133
                del sys.modules[entry]
 
134
        if verbose: print("  Removed sys.modules entries")
 
135
        del sys.path[0]
 
136
        if verbose: print("  Removed sys.path entry")
 
137
        for root, dirs, files in os.walk(top, topdown=False):
 
138
            for name in files:
 
139
                try:
 
140
                    os.remove(os.path.join(root, name))
 
141
                except OSError as ex:
 
142
                    if verbose: print(ex) # Persist with cleaning up
 
143
            for name in dirs:
 
144
                fullname = os.path.join(root, name)
 
145
                try:
 
146
                    os.rmdir(fullname)
 
147
                except OSError as ex:
 
148
                    if verbose: print(ex) # Persist with cleaning up
 
149
        try:
 
150
            os.rmdir(top)
 
151
            if verbose: print("  Removed package tree")
 
152
        except OSError as ex:
 
153
            if verbose: print(ex) # Persist with cleaning up
 
154
 
 
155
    def _check_module(self, depth):
 
156
        pkg_dir, mod_fname, mod_name = (
 
157
               self._make_pkg("x=1\n", depth))
 
158
        forget(mod_name)
 
159
        try:
 
160
            if verbose: print("Running from source:", mod_name)
 
161
            d1 = run_module(mod_name) # Read from source
 
162
            self.failUnless("x" in d1)
 
163
            self.assertEqual(d1["x"], 1)
 
164
            del d1 # Ensure __loader__ entry doesn't keep file open
 
165
            __import__(mod_name)
 
166
            os.remove(mod_fname)
 
167
            if verbose: print("Running from compiled:", mod_name)
 
168
            d2 = run_module(mod_name) # Read from bytecode
 
169
            self.failUnless("x" in d2)
 
170
            self.assertEqual(d2["x"], 1)
 
171
            del d2 # Ensure __loader__ entry doesn't keep file open
 
172
        finally:
 
173
            self._del_pkg(pkg_dir, depth, mod_name)
 
174
        if verbose: print("Module executed successfully")
 
175
 
 
176
    def _add_relative_modules(self, base_dir, source, depth):
 
177
        if depth <= 1:
 
178
            raise ValueError("Relative module test needs depth > 1")
 
179
        pkg_name = "__runpy_pkg__"
 
180
        module_dir = base_dir
 
181
        for i in range(depth):
 
182
            parent_dir = module_dir
 
183
            module_dir = os.path.join(module_dir, pkg_name)
 
184
        # Add sibling module
 
185
        sibling_fname = os.path.join(module_dir, "sibling.py")
 
186
        sibling_file = open(sibling_fname, "w")
 
187
        sibling_file.close()
 
188
        if verbose: print("  Added sibling module:", sibling_fname)
 
189
        # Add nephew module
 
190
        uncle_dir = os.path.join(parent_dir, "uncle")
 
191
        self._add_pkg_dir(uncle_dir)
 
192
        if verbose: print("  Added uncle package:", uncle_dir)
 
193
        cousin_dir = os.path.join(uncle_dir, "cousin")
 
194
        self._add_pkg_dir(cousin_dir)
 
195
        if verbose: print("  Added cousin package:", cousin_dir)
 
196
        nephew_fname = os.path.join(cousin_dir, "nephew.py")
 
197
        nephew_file = open(nephew_fname, "w")
 
198
        nephew_file.close()
 
199
        if verbose: print("  Added nephew module:", nephew_fname)
 
200
 
 
201
    def _check_relative_imports(self, depth, run_name=None):
 
202
        contents = r"""\
 
203
from __future__ import absolute_import
 
204
from . import sibling
 
205
from ..uncle.cousin import nephew
 
206
"""
 
207
        pkg_dir, mod_fname, mod_name = (
 
208
               self._make_pkg(contents, depth))
 
209
        try:
 
210
            self._add_relative_modules(pkg_dir, contents, depth)
 
211
            pkg_name = mod_name.rpartition('.')[0]
 
212
            if verbose: print("Running from source:", mod_name)
 
213
            d1 = run_module(mod_name, run_name=run_name) # Read from source
 
214
            self.failUnless("__package__" in d1)
 
215
            self.failUnless(d1["__package__"] == pkg_name)
 
216
            self.failUnless("sibling" in d1)
 
217
            self.failUnless("nephew" in d1)
 
218
            del d1 # Ensure __loader__ entry doesn't keep file open
 
219
            __import__(mod_name)
 
220
            os.remove(mod_fname)
 
221
            if verbose: print("Running from compiled:", mod_name)
 
222
            d2 = run_module(mod_name, run_name=run_name) # Read from bytecode
 
223
            self.failUnless("__package__" in d2)
 
224
            self.failUnless(d2["__package__"] == pkg_name)
 
225
            self.failUnless("sibling" in d2)
 
226
            self.failUnless("nephew" in d2)
 
227
            del d2 # Ensure __loader__ entry doesn't keep file open
 
228
        finally:
 
229
            self._del_pkg(pkg_dir, depth, mod_name)
 
230
        if verbose: print("Module executed successfully")
 
231
 
 
232
    def test_run_module(self):
 
233
        for depth in range(4):
 
234
            if verbose: print("Testing package depth:", depth)
 
235
            self._check_module(depth)
 
236
 
 
237
    def test_explicit_relative_import(self):
 
238
        for depth in range(2, 5):
 
239
            if verbose: print("Testing relative imports at depth:", depth)
 
240
            self._check_relative_imports(depth)
 
241
 
 
242
    def test_main_relative_import(self):
 
243
        for depth in range(2, 5):
 
244
            if verbose: print("Testing main relative imports at depth:", depth)
 
245
            self._check_relative_imports(depth, "__main__")
 
246
 
 
247
 
 
248
def test_main():
 
249
    run_unittest(RunModuleCodeTest)
 
250
    run_unittest(RunModuleTest)
 
251
 
 
252
if __name__ == "__main__":
 
253
    test_main()