Commit e2ebb2d7 authored by Nick Coghlan's avatar Nick Coghlan

Implement PEP 338 which has been marked as accepted by GvR

parent 8ea61f1a
This diff is collapsed.
# Test the runpy module
import unittest
import os
import os.path
import sys
import tempfile
from test.test_support import verbose, run_unittest
from runpy import _run_module_code, run_module
# Set up the test code and expected results
class RunModuleCodeTest(unittest.TestCase):
expected_result = ["Top level assignment", "Lower level reference"]
test_source = (
"# Check basic code execution\n"
"result = ['Top level assignment']\n"
"def f():\n"
" result.append('Lower level reference')\n"
"f()\n"
"# Check the sys module\n"
"import sys\n"
"run_argv0 = sys.argv[0]\n"
"if __name__ in sys.modules:\n"
" run_name = sys.modules[__name__].__name__\n"
"# Check nested operation\n"
"import runpy\n"
"nested = runpy._run_module_code('x=1\\n', mod_name='<run>',\n"
" alter_sys=True)\n"
)
def test_run_module_code(self):
initial = object()
name = "<Nonsense>"
file = "Some other nonsense"
loader = "Now you're just being silly"
d1 = dict(initial=initial)
saved_argv0 = sys.argv[0]
d2 = _run_module_code(self.test_source,
d1,
name,
file,
loader,
True)
self.failUnless("result" not in d1)
self.failUnless(d2["initial"] is initial)
self.failUnless(d2["result"] == self.expected_result)
self.failUnless(d2["nested"]["x"] == 1)
self.failUnless(d2["__name__"] is name)
self.failUnless(d2["run_name"] is name)
self.failUnless(d2["__file__"] is file)
self.failUnless(d2["run_argv0"] is file)
self.failUnless(d2["__loader__"] is loader)
self.failUnless(sys.argv[0] is saved_argv0)
self.failUnless(name not in sys.modules)
def test_run_module_code_defaults(self):
saved_argv0 = sys.argv[0]
d = _run_module_code(self.test_source)
self.failUnless(d["result"] == self.expected_result)
self.failUnless(d["__name__"] is None)
self.failUnless(d["__file__"] is None)
self.failUnless(d["__loader__"] is None)
self.failUnless(d["run_argv0"] is saved_argv0)
self.failUnless("run_name" not in d)
self.failUnless(sys.argv[0] is saved_argv0)
class RunModuleTest(unittest.TestCase):
def expect_import_error(self, mod_name):
try:
run_module(mod_name)
except ImportError:
pass
else:
self.fail("Expected import error for " + mod_name)
def test_invalid_names(self):
self.expect_import_error("sys")
self.expect_import_error("sys.imp.eric")
self.expect_import_error("os.path.half")
self.expect_import_error("a.bee")
self.expect_import_error(".howard")
self.expect_import_error("..eaten")
def test_library_module(self):
run_module("runpy")
def _make_pkg(self, source, depth):
pkg_name = "__runpy_pkg__"
init_fname = "__init__"+os.extsep+"py"
test_fname = "runpy_test"+os.extsep+"py"
pkg_dir = sub_dir = tempfile.mkdtemp()
if verbose: print " Package tree in:", sub_dir
sys.path.insert(0, pkg_dir)
if verbose: print " Updated sys.path:", sys.path[0]
for i in range(depth):
sub_dir = os.path.join(sub_dir, pkg_name)
os.mkdir(sub_dir)
if verbose: print " Next level in:", sub_dir
pkg_fname = os.path.join(sub_dir, init_fname)
pkg_file = open(pkg_fname, "w")
pkg_file.write("__path__ = ['%s']\n" % sub_dir)
pkg_file.close()
if verbose: print " Created:", pkg_fname
mod_fname = os.path.join(sub_dir, test_fname)
mod_file = open(mod_fname, "w")
mod_file.write(source)
mod_file.close()
if verbose: print " Created:", mod_fname
mod_name = (pkg_name+".")*depth + "runpy_test"
return pkg_dir, mod_fname, mod_name
def _del_pkg(self, top, depth, mod_name):
for root, dirs, files in os.walk(top, topdown=False):
for name in files:
os.remove(os.path.join(root, name))
for name in dirs:
os.rmdir(os.path.join(root, name))
os.rmdir(top)
if verbose: print " Removed package tree"
for i in range(depth+1): # Don't forget the module itself
parts = mod_name.rsplit(".", i)
entry = parts[0]
del sys.modules[entry]
if verbose: print " Removed sys.modules entries"
del sys.path[0]
if verbose: print " Removed sys.path entry"
def _check_module(self, depth):
pkg_dir, mod_fname, mod_name = (
self._make_pkg("x=1\n", depth))
try:
if verbose: print "Running from source:", mod_name
d1 = run_module(mod_name) # Read from source
__import__(mod_name)
os.remove(mod_fname)
if verbose: print "Running from compiled:", mod_name
d2 = run_module(mod_name) # Read from bytecode
finally:
self._del_pkg(pkg_dir, depth, mod_name)
self.failUnless(d1["x"] == d2["x"] == 1)
if verbose: print "Module executed successfully"
def test_run_module(self):
for depth in range(4):
if verbose: print "Testing package depth:", depth
self._check_module(depth)
def test_main():
run_unittest(RunModuleCodeTest)
run_unittest(RunModuleTest)
if __name__ == "__main__":
test_main()
\ No newline at end of file
...@@ -132,27 +132,42 @@ static void RunStartupFile(PyCompilerFlags *cf) ...@@ -132,27 +132,42 @@ static void RunStartupFile(PyCompilerFlags *cf)
} }
} }
/* Get the path to a top-level module */
static struct filedescr * FindModule(const char *module,
FILE **fp, char **filename)
{
struct filedescr *fdescr = NULL;
*fp = NULL;
*filename = malloc(MAXPATHLEN);
if (*filename == NULL)
return NULL;
/* Find the actual module source code */ static int RunModule(char *module)
fdescr = _PyImport_FindModule(module, NULL, {
*filename, MAXPATHLEN, fp, NULL); PyObject *runpy, *runmodule, *runargs, *result;
runpy = PyImport_ImportModule("runpy");
if (fdescr == NULL) { if (runpy == NULL) {
free(*filename); fprintf(stderr, "Could not import runpy module\n");
*filename = NULL; return -1;
} }
runmodule = PyObject_GetAttrString(runpy, "run_module");
return fdescr; if (runmodule == NULL) {
fprintf(stderr, "Could not access runpy.run_module\n");
Py_DECREF(runpy);
return -1;
}
runargs = Py_BuildValue("sOsO", module,
Py_None, "__main__", Py_True);
if (runargs == NULL) {
fprintf(stderr,
"Could not create arguments for runpy.run_module\n");
Py_DECREF(runpy);
Py_DECREF(runmodule);
return -1;
}
result = PyObject_Call(runmodule, runargs, NULL);
if (result == NULL) {
PyErr_Print();
}
Py_DECREF(runpy);
Py_DECREF(runmodule);
Py_DECREF(runargs);
if (result == NULL) {
return -1;
}
Py_DECREF(result);
return 0;
} }
/* Main program */ /* Main program */
...@@ -441,28 +456,9 @@ Py_Main(int argc, char **argv) ...@@ -441,28 +456,9 @@ Py_Main(int argc, char **argv)
} }
if (module != NULL) { if (module != NULL) {
/* Backup _PyOS_optind and find the real file */ /* Backup _PyOS_optind and force sys.arv[0] = module */
struct filedescr *fdescr = NULL;
_PyOS_optind--; _PyOS_optind--;
if ((fdescr = FindModule(module, &fp, &filename))) { argv[_PyOS_optind] = module;
argv[_PyOS_optind] = filename;
} else {
fprintf(stderr, "%s: module %s not found\n",
argv[0], module);
return 2;
}
if (!fp) {
fprintf(stderr,
"%s: module %s has no associated file\n",
argv[0], module);
return 2;
}
if (!_PyImport_IsScript(fdescr)) {
fprintf(stderr,
"%s: module %s not usable as script\n (%s)\n",
argv[0], module, filename);
return 2;
}
} }
PySys_SetArgv(argc-_PyOS_optind, argv+_PyOS_optind); PySys_SetArgv(argc-_PyOS_optind, argv+_PyOS_optind);
...@@ -481,9 +477,8 @@ Py_Main(int argc, char **argv) ...@@ -481,9 +477,8 @@ Py_Main(int argc, char **argv)
sts = PyRun_SimpleStringFlags(command, &cf) != 0; sts = PyRun_SimpleStringFlags(command, &cf) != 0;
free(command); free(command);
} else if (module) { } else if (module) {
sts = PyRun_AnyFileExFlags(fp, filename, 1, &cf) != 0; sts = RunModule(module);
free(module); free(module);
free(filename);
} }
else { else {
if (filename == NULL && stdin_is_interactive) { if (filename == NULL && stdin_is_interactive) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment