Revert misguided attempt at fixing incompatibility between -m and -i switches (better fix coming soon)

This commit is contained in:
Nick Coghlan 2007-08-25 04:32:07 +00:00
parent 68f525fdc8
commit 3af0e785e7
4 changed files with 55 additions and 45 deletions

View file

@ -52,11 +52,9 @@ The :mod:`runpy` module provides a single function:
If the argument *alter_sys* is supplied and evaluates to ``True``, then If the argument *alter_sys* is supplied and evaluates to ``True``, then
``sys.argv[0]`` is updated with the value of ``__file__`` and ``sys.argv[0]`` is updated with the value of ``__file__`` and
``sys.modules[__name__]`` is updated with a new module object for the module ``sys.modules[__name__]`` is updated with a temporary module object for the
being executed. Note that neither ``sys.argv[0]`` nor ``sys.modules[__name__]`` module being executed. Both ``sys.argv[0]`` and ``sys.modules[__name__]``
are restored to their original values before the function returns - if client are restored to their original values before the function returns.
code needs these values preserved, it must either save them explicitly or else
avoid enabling the automatic alterations to :mod:`sys`.
Note that this manipulation of :mod:`sys` is not thread-safe. Other threads may Note that this manipulation of :mod:`sys` is not thread-safe. Other threads may
see the partially initialised module, as well as the altered list of arguments. see the partially initialised module, as well as the altered list of arguments.

View file

@ -38,15 +38,30 @@ def _run_module_code(code, init_globals=None,
"""Helper for run_module""" """Helper for run_module"""
# Set up the top level namespace dictionary # Set up the top level namespace dictionary
if alter_sys: if alter_sys:
# Modify sys.argv[0] and sys.modules[mod_name] # Modify sys.argv[0] and sys.module[mod_name]
temp_module = imp.new_module(mod_name)
mod_globals = temp_module.__dict__
saved_argv0 = sys.argv[0]
restore_module = mod_name in sys.modules
if restore_module:
saved_module = sys.modules[mod_name]
sys.argv[0] = mod_fname sys.argv[0] = mod_fname
module = imp.new_module(mod_name) sys.modules[mod_name] = temp_module
sys.modules[mod_name] = module try:
mod_globals = module.__dict__ _run_code(code, mod_globals, init_globals,
mod_name, mod_fname, mod_loader)
finally:
sys.argv[0] = saved_argv0
if restore_module:
sys.modules[mod_name] = saved_module
else:
del sys.modules[mod_name]
# Copy the globals of the temporary module, as they
# may be cleared when the temporary module goes away
return mod_globals.copy()
else: else:
# Leave the sys module alone # Leave the sys module alone
mod_globals = {} return _run_code(code, {}, init_globals,
return _run_code(code, mod_globals, init_globals,
mod_name, mod_fname, mod_loader) mod_name, mod_fname, mod_loader)

View file

@ -26,7 +26,8 @@ class RunModuleCodeTest(unittest.TestCase):
" module_in_sys_modules = globals() is sys.modules[__name__].__dict__\n" " module_in_sys_modules = globals() is sys.modules[__name__].__dict__\n"
"# Check nested operation\n" "# Check nested operation\n"
"import runpy\n" "import runpy\n"
"nested = runpy._run_module_code('x=1\\n', mod_name='<run>')\n" "nested = runpy._run_module_code('x=1\\n', mod_name='<run>',\n"
" alter_sys=True)\n"
) )
@ -37,44 +38,35 @@ class RunModuleCodeTest(unittest.TestCase):
loader = "Now you're just being silly" loader = "Now you're just being silly"
d1 = dict(initial=initial) d1 = dict(initial=initial)
saved_argv0 = sys.argv[0] saved_argv0 = sys.argv[0]
try:
d2 = _run_module_code(self.test_source, d2 = _run_module_code(self.test_source,
d1, d1,
name, name,
file, file,
loader, loader,
alter_sys=True) True)
self.failUnless("result" not in d1) self.failUnless("result" not in d1)
self.failUnless(d2["initial"] is initial) self.failUnless(d2["initial"] is initial)
self.failUnless(d2["result"] == self.expected_result) self.failUnless(d2["result"] == self.expected_result)
self.failUnless(d2["nested"]["x"] == 1) self.failUnless(d2["nested"]["x"] == 1)
self.failUnless(d2["nested"]["__name__"] == "<run>")
self.failUnless(d2["__name__"] is name) self.failUnless(d2["__name__"] is name)
self.failUnless(d2["__file__"] is file)
self.failUnless(d2["__loader__"] is loader)
self.failUnless(d2["run_argv0"] is file)
self.failUnless(d2["run_name_in_sys_modules"]) self.failUnless(d2["run_name_in_sys_modules"])
self.failUnless(d2["module_in_sys_modules"]) self.failUnless(d2["module_in_sys_modules"])
self.failUnless(sys.argv[0] is not saved_argv0) self.failUnless(d2["__file__"] is file)
self.failUnless(name in sys.modules) self.failUnless(d2["run_argv0"] is file)
finally: self.failUnless(d2["__loader__"] is loader)
sys.argv[0] = saved_argv0 self.failUnless(sys.argv[0] is saved_argv0)
if name in sys.modules: self.failUnless(name not in sys.modules)
del sys.modules[name]
def test_run_module_code_defaults(self): def test_run_module_code_defaults(self):
saved_argv0 = sys.argv[0] saved_argv0 = sys.argv[0]
d = _run_module_code(self.test_source) d = _run_module_code(self.test_source)
self.failUnless(d["result"] == self.expected_result) self.failUnless(d["result"] == self.expected_result)
self.failUnless(d["nested"]["x"] == 1)
self.failUnless(d["nested"]["__name__"] == "<run>")
self.failUnless(d["__name__"] is None) self.failUnless(d["__name__"] is None)
self.failUnless(d["__file__"] is None) self.failUnless(d["__file__"] is None)
self.failUnless(d["__loader__"] is None) self.failUnless(d["__loader__"] is None)
self.failUnless(d["run_argv0"] is saved_argv0) self.failUnless(d["run_argv0"] is saved_argv0)
self.failUnless(not d["run_name_in_sys_modules"]) self.failUnless("run_name" not in d)
self.failUnless(sys.argv[0] is saved_argv0) self.failUnless(sys.argv[0] is saved_argv0)
self.failUnless(None not in sys.modules)
class RunModuleTest(unittest.TestCase): class RunModuleTest(unittest.TestCase):

View file

@ -1616,10 +1616,14 @@ compiler_while(struct compiler *c, stmt_ty s)
orelse = NULL; orelse = NULL;
ADDOP_JREL(c, SETUP_LOOP, end); ADDOP_JREL(c, SETUP_LOOP, end);
compiler_use_next_block(c, loop);
if (!compiler_push_fblock(c, LOOP, loop)) if (!compiler_push_fblock(c, LOOP, loop))
return 0; return 0;
compiler_use_next_block(c, loop);
if (constant == -1) { if (constant == -1) {
/* XXX(ncoghlan): SF bug #1750076
Use same special casing as is used in for loops
A test case for this would be nice... */
c->u->u_lineno_set = false;
VISIT(c, expr, s->v.While.test); VISIT(c, expr, s->v.While.test);
ADDOP_JREL(c, JUMP_IF_FALSE, anchor); ADDOP_JREL(c, JUMP_IF_FALSE, anchor);
ADDOP(c, POP_TOP); ADDOP(c, POP_TOP);
@ -3521,7 +3525,8 @@ assemble_lnotab(struct assembler *a, struct instr *i)
/* XXX(nnorwitz): is there a better way to handle this? /* XXX(nnorwitz): is there a better way to handle this?
for loops are special, we want to be able to trace them for loops are special, we want to be able to trace them
each time around, so we need to set an extra line number. */ each time around, so we need to set an extra line number. */
if (d_lineno == 0 && i->i_opcode != FOR_ITER) /* XXX(ncoghlan): while loops need this too */
if (d_lineno == 0)
return 1; return 1;
if (d_bytecode > 255) { if (d_bytecode > 255) {