Commit 7625b86d authored by Kevin Modzelewski's avatar Kevin Modzelewski

Have function.func_globals always be dict-like

Internally we store it as either-dict-or-module, but when we expose
it to Python it needs to be given back as a mapping.  I looked briefly
into switching the internal representation, but that seemed like a much
more invasive change.

Also, add a pytest test that exposed this issue.
parent 6a33d150
......@@ -305,6 +305,9 @@ extern "C" BoxedFunctionBase::BoxedFunctionBase(FunctionMetadata* md, llvm::Arra
doc(NULL) {
assert((!globals) == (!md->source || md->source->scoping->areGlobalsFromModule()));
if (globals)
ASSERT(globals->cls == dict_cls || globals->cls == module_cls, "%s", globals->cls->tp_name);
Py_XINCREF(closure);
Py_XINCREF(globals);
......@@ -1699,6 +1702,8 @@ static Box* function_globals(Box* self, void*) noexcept {
BoxedFunction* func = static_cast<BoxedFunction*>(self);
if (func->globals) {
assert(!func->md->source || !func->md->source->scoping->areGlobalsFromModule());
if (func->globals->cls == module_cls)
return incref(func->globals->getAttrWrapper());
return incref(func->globals);
}
assert(func->md->source);
......
import os, sys, subprocess, shutil
sys.path.append(os.path.dirname(__file__) + "/../lib")
from test_helper import create_virtenv, run_test
ENV_NAME = "pytest_test_env_" + os.path.basename(sys.executable)
ENV_DIR = os.path.abspath(ENV_NAME)
SRC_DIR = os.path.abspath(os.path.join(ENV_NAME, "src"))
PYTHON_EXE = os.path.abspath(os.path.join(ENV_NAME, "bin", "python"))
pkg = ["pytest==2.8.2"]
create_virtenv(ENV_NAME, pkg)
PYTEST_DIR = os.path.abspath(os.path.join(SRC_DIR, "pytest"))
test_dir = os.path.join(ENV_DIR, "tests")
if not os.path.exists(test_dir):
os.mkdir(test_dir)
with open(os.path.join(test_dir, "test_foo.py"), 'w') as f:
f.write("""
import pytest
@pytest.mark.skipif(True, reason="for fun")
def test_skipif_true():
1/0
""")
subprocess.check_call([os.path.join(ENV_DIR, "bin", "py.test"), test_dir])
# subprocess.check_call(["gdb", "--args", PYTHON_EXE, "-m", "pytest", test_dir])
......@@ -97,3 +97,19 @@ g2 = copyfunc(g)
assert g.func_defaults == g2.func_defaults, (g.func_defaults, g2.func_defaults)
g(1)
g2(2)
# Regression test: make sure that __globals__/func_globals gets set
# properly in exec cases
d = {}
exec """
def f():
pass
""" in d
assert type(d['f'].__globals__) == dict
exec """
def f():
pass
""" in globals()
assert type(globals()['f'].__globals__) == type(globals())
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