Skip to content

Commit 3cfddbc

Browse files
Fall back to __main__.__dict__ if running main.
1 parent 39afdac commit 3cfddbc

File tree

4 files changed

+86
-13
lines changed

4 files changed

+86
-13
lines changed

Include/internal/pycore_ceval.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ static inline void _Py_LeaveRecursiveCall(void) {
239239

240240
extern _PyInterpreterFrame* _PyEval_GetFrame(void);
241241

242+
extern PyObject * _PyEval_GetGlobalsFromRunningMain(PyThreadState *);
242243
extern int _PyEval_EnsureBuiltins(
243244
PyThreadState *,
244245
PyObject *,

Objects/object.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2083,9 +2083,23 @@ _dir_locals(void)
20832083
PyObject *names;
20842084
PyObject *locals;
20852085

2086-
locals = _PyEval_GetFrameLocals();
2087-
if (locals == NULL)
2086+
if (_PyEval_GetFrame() != NULL) {
2087+
locals = _PyEval_GetFrameLocals();
2088+
}
2089+
PyThreadState *tstate = _PyThreadState_GET();
2090+
locals = _PyEval_GetGlobalsFromRunningMain(tstate);
2091+
if (locals == NULL) {
2092+
if (!_PyErr_Occurred(tstate)) {
2093+
locals = _PyEval_GetFrameLocals();
2094+
assert(_PyErr_Occurred(tstate));
2095+
}
2096+
}
2097+
else {
2098+
Py_INCREF(locals);
2099+
}
2100+
if (locals == NULL) {
20882101
return NULL;
2102+
}
20892103

20902104
names = PyMapping_Keys(locals);
20912105
Py_DECREF(locals);

Python/bltinmodule.c

Lines changed: 53 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -983,10 +983,16 @@ builtin_eval_impl(PyObject *module, PyObject *source, PyObject *globals,
983983
Py_INCREF(globals);
984984
}
985985
else {
986-
PyErr_SetString(PyExc_TypeError,
987-
"eval must be given globals and locals "
988-
"when called without a frame");
989-
return NULL;
986+
globals = _PyEval_GetGlobalsFromRunningMain(tstate);
987+
if (globals == NULL) {
988+
if (!_PyErr_Occurred(tstate)) {
989+
PyErr_SetString(PyExc_TypeError,
990+
"eval must be given globals and locals "
991+
"when called without a frame");
992+
}
993+
return NULL;
994+
}
995+
Py_INCREF(globals);
990996
}
991997

992998
if (locals != Py_None) {
@@ -1090,9 +1096,15 @@ builtin_exec_impl(PyObject *module, PyObject *source, PyObject *globals,
10901096
Py_INCREF(globals);
10911097
}
10921098
else {
1093-
PyErr_SetString(PyExc_SystemError,
1094-
"globals and locals cannot be NULL");
1095-
goto error;
1099+
globals = _PyEval_GetGlobalsFromRunningMain(tstate);
1100+
if (globals == NULL) {
1101+
if (!_PyErr_Occurred(tstate)) {
1102+
PyErr_SetString(PyExc_SystemError,
1103+
"globals and locals cannot be NULL");
1104+
}
1105+
goto error;
1106+
}
1107+
Py_INCREF(globals);
10961108
}
10971109

10981110
if (locals != Py_None) {
@@ -1255,12 +1267,21 @@ static PyObject *
12551267
builtin_globals_impl(PyObject *module)
12561268
/*[clinic end generated code: output=e5dd1527067b94d2 input=9327576f92bb48ba]*/
12571269
{
1270+
PyObject *globals;
12581271
if (_PyEval_GetFrame() != NULL) {
1259-
PyObject *globals = PyEval_GetGlobals();
1272+
globals = PyEval_GetGlobals();
12601273
assert(globals != NULL);
12611274
return Py_NewRef(globals);
12621275
}
1263-
Py_RETURN_NONE;
1276+
PyThreadState *tstate = _PyThreadState_GET();
1277+
globals = _PyEval_GetGlobalsFromRunningMain(tstate);
1278+
if (globals == NULL) {
1279+
if (_PyErr_Occurred(tstate)) {
1280+
return NULL;
1281+
}
1282+
Py_RETURN_NONE;
1283+
}
1284+
return Py_NewRef(globals);
12641285
}
12651286

12661287

@@ -1910,7 +1931,15 @@ builtin_locals_impl(PyObject *module)
19101931
assert(locals != NULL || PyErr_Occurred());
19111932
return locals;
19121933
}
1913-
Py_RETURN_NONE;
1934+
PyThreadState *tstate = _PyThreadState_GET();
1935+
locals = _PyEval_GetGlobalsFromRunningMain(tstate);
1936+
if (locals == NULL) {
1937+
if (_PyErr_Occurred(tstate)) {
1938+
return NULL;
1939+
}
1940+
Py_RETURN_NONE;
1941+
}
1942+
return Py_NewRef(locals);
19141943
}
19151944

19161945

@@ -2646,7 +2675,20 @@ builtin_vars(PyObject *self, PyObject *args)
26462675
if (!PyArg_UnpackTuple(args, "vars", 0, 1, &v))
26472676
return NULL;
26482677
if (v == NULL) {
2649-
d = _PyEval_GetFrameLocals();
2678+
if (_PyEval_GetFrame() != NULL) {
2679+
d = _PyEval_GetFrameLocals();
2680+
}
2681+
PyThreadState *tstate = _PyThreadState_GET();
2682+
d = _PyEval_GetGlobalsFromRunningMain(tstate);
2683+
if (d == NULL) {
2684+
if (!_PyErr_Occurred(tstate)) {
2685+
d = _PyEval_GetFrameLocals();
2686+
assert(_PyErr_Occurred(tstate));
2687+
}
2688+
}
2689+
else {
2690+
Py_INCREF(d);
2691+
}
26502692
}
26512693
else {
26522694
if (PyObject_GetOptionalAttr(v, &_Py_ID(__dict__), &d) == 0) {

Python/ceval.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2763,6 +2763,22 @@ PyEval_GetGlobals(void)
27632763
return _PyEval_GetGlobals(tstate);
27642764
}
27652765

2766+
PyObject *
2767+
_PyEval_GetGlobalsFromRunningMain(PyThreadState *tstate)
2768+
{
2769+
if (!_PyInterpreterState_IsRunningMain(tstate->interp)) {
2770+
return NULL;
2771+
}
2772+
PyObject *mod = _Py_GetMainModule(tstate);
2773+
if (_Py_CheckMainModule(mod) < 0) {
2774+
Py_XDECREF(mod);
2775+
return NULL;
2776+
}
2777+
PyObject *globals = PyModule_GetDict(mod); // borrowed
2778+
Py_DECREF(mod);
2779+
return globals;
2780+
}
2781+
27662782
int
27672783
_PyEval_EnsureBuiltins(PyThreadState *tstate, PyObject *globals, int usemod,
27682784
PyObject **p_builtins)

0 commit comments

Comments
 (0)