Kaydet (Commit) 3af0e785 authored tarafından Nick Coghlan's avatar Nick Coghlan

Revert misguided attempt at fixing incompatibility between -m and -i switches…

Revert misguided attempt at fixing incompatibility between -m and -i switches (better fix coming soon)
üst 68f525fd
...@@ -52,11 +52,9 @@ The :mod:`runpy` module provides a single function: ...@@ -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.
......
...@@ -33,21 +33,36 @@ def _run_code(code, run_globals, init_globals, ...@@ -33,21 +33,36 @@ def _run_code(code, run_globals, init_globals,
return run_globals return run_globals
def _run_module_code(code, init_globals=None, def _run_module_code(code, init_globals=None,
mod_name=None, mod_fname=None, mod_name=None, mod_fname=None,
mod_loader=None, alter_sys=False): mod_loader=None, alter_sys=False):
"""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)
# This helper is needed due to a missing component in the PEP 302 # This helper is needed due to a missing component in the PEP 302
......
...@@ -26,7 +26,8 @@ class RunModuleCodeTest(unittest.TestCase): ...@@ -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): ...@@ -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, True)
alter_sys=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["__name__"] is name)
self.failUnless(d2["nested"]["__name__"] == "<run>") self.failUnless(d2["run_name_in_sys_modules"])
self.failUnless(d2["__name__"] is name) self.failUnless(d2["module_in_sys_modules"])
self.failUnless(d2["__file__"] is file) self.failUnless(d2["__file__"] is file)
self.failUnless(d2["__loader__"] is loader) self.failUnless(d2["run_argv0"] is file)
self.failUnless(d2["run_argv0"] is file) self.failUnless(d2["__loader__"] is loader)
self.failUnless(d2["run_name_in_sys_modules"]) self.failUnless(sys.argv[0] is saved_argv0)
self.failUnless(d2["module_in_sys_modules"]) self.failUnless(name not in sys.modules)
self.failUnless(sys.argv[0] is not saved_argv0)
self.failUnless(name in sys.modules)
finally:
sys.argv[0] = saved_argv0
if name 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):
......
...@@ -1616,10 +1616,14 @@ compiler_while(struct compiler *c, stmt_ty s) ...@@ -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) ...@@ -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) {
......
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