Skip to content

Commit 39afdac

Browse files
Refactor before adding _PyEval_GetGlobalsFromRunningMain().
1 parent 54ea52b commit 39afdac

File tree

4 files changed

+131
-55
lines changed

4 files changed

+131
-55
lines changed

Include/internal/pycore_ceval.h

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

240240
extern _PyInterpreterFrame* _PyEval_GetFrame(void);
241241

242+
extern int _PyEval_EnsureBuiltins(
243+
PyThreadState *,
244+
PyObject *,
245+
int usemod,
246+
PyObject **p_builtins);
247+
242248
PyAPI_FUNC(PyObject *)_Py_MakeCoro(PyFunctionObject *func);
243249

244250
/* Handle signals, pending calls, GIL drop request

Python/bltinmodule.c

Lines changed: 69 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -957,6 +957,7 @@ builtin_eval_impl(PyObject *module, PyObject *source, PyObject *globals,
957957
PyObject *locals)
958958
/*[clinic end generated code: output=0a0824aa70093116 input=7c7bce5299a89062]*/
959959
{
960+
PyThreadState *tstate = _PyThreadState_GET();
960961
PyObject *result = NULL, *source_copy;
961962
const char *str;
962963

@@ -970,35 +971,40 @@ builtin_eval_impl(PyObject *module, PyObject *source, PyObject *globals,
970971
: "globals must be a dict");
971972
return NULL;
972973
}
973-
if (globals == Py_None) {
974+
975+
int fromframe = 0;
976+
if (globals != Py_None) {
977+
Py_INCREF(globals);
978+
}
979+
else if (_PyEval_GetFrame() != NULL) {
980+
fromframe = 1;
974981
globals = PyEval_GetGlobals();
975-
if (locals == Py_None) {
976-
locals = _PyEval_GetFrameLocals();
977-
if (locals == NULL)
978-
return NULL;
979-
}
980-
else {
981-
Py_INCREF(locals);
982-
}
982+
assert(globals != NULL);
983+
Py_INCREF(globals);
983984
}
984-
else if (locals == Py_None)
985-
locals = Py_NewRef(globals);
986985
else {
987-
Py_INCREF(locals);
988-
}
989-
990-
if (globals == NULL || locals == NULL) {
991986
PyErr_SetString(PyExc_TypeError,
992987
"eval must be given globals and locals "
993988
"when called without a frame");
994-
goto error;
989+
return NULL;
995990
}
996991

997-
int r = PyDict_Contains(globals, &_Py_ID(__builtins__));
998-
if (r == 0) {
999-
r = PyDict_SetItem(globals, &_Py_ID(__builtins__), PyEval_GetBuiltins());
992+
if (locals != Py_None) {
993+
Py_INCREF(locals);
994+
}
995+
else if (fromframe) {
996+
locals = _PyEval_GetFrameLocals();
997+
if (locals == NULL) {
998+
assert(PyErr_Occurred());
999+
Py_DECREF(globals);
1000+
return NULL;
1001+
}
10001002
}
1001-
if (r < 0) {
1003+
else {
1004+
locals = Py_NewRef(globals);
1005+
}
1006+
1007+
if (_PyEval_EnsureBuiltins(tstate, globals, 0, NULL) < 0) {
10021008
goto error;
10031009
}
10041010

@@ -1039,6 +1045,7 @@ builtin_eval_impl(PyObject *module, PyObject *source, PyObject *globals,
10391045
}
10401046

10411047
error:
1048+
Py_XDECREF(globals);
10421049
Py_XDECREF(locals);
10431050
return result;
10441051
}
@@ -1069,29 +1076,38 @@ builtin_exec_impl(PyObject *module, PyObject *source, PyObject *globals,
10691076
PyObject *locals, PyObject *closure)
10701077
/*[clinic end generated code: output=7579eb4e7646743d input=25e989b6d87a3a21]*/
10711078
{
1079+
PyThreadState *tstate = _PyThreadState_GET();
10721080
PyObject *v;
10731081

1074-
if (globals == Py_None) {
1082+
int fromframe = 0;
1083+
if (globals != Py_None) {
1084+
Py_INCREF(globals);
1085+
}
1086+
else if (_PyEval_GetFrame() != NULL) {
1087+
fromframe = 1;
10751088
globals = PyEval_GetGlobals();
1076-
if (locals == Py_None) {
1077-
locals = _PyEval_GetFrameLocals();
1078-
if (locals == NULL)
1079-
return NULL;
1080-
}
1081-
else {
1082-
Py_INCREF(locals);
1083-
}
1084-
if (!globals || !locals) {
1085-
PyErr_SetString(PyExc_SystemError,
1086-
"globals and locals cannot be NULL");
1089+
assert(globals != NULL);
1090+
Py_INCREF(globals);
1091+
}
1092+
else {
1093+
PyErr_SetString(PyExc_SystemError,
1094+
"globals and locals cannot be NULL");
1095+
goto error;
1096+
}
1097+
1098+
if (locals != Py_None) {
1099+
Py_INCREF(locals);
1100+
}
1101+
else if (fromframe) {
1102+
locals = _PyEval_GetFrameLocals();
1103+
if (locals == NULL) {
1104+
assert(PyErr_Occurred());
1105+
Py_DECREF(globals);
10871106
return NULL;
10881107
}
10891108
}
1090-
else if (locals == Py_None) {
1091-
locals = Py_NewRef(globals);
1092-
}
10931109
else {
1094-
Py_INCREF(locals);
1110+
locals = Py_NewRef(globals);
10951111
}
10961112

10971113
if (!PyDict_Check(globals)) {
@@ -1105,11 +1121,8 @@ builtin_exec_impl(PyObject *module, PyObject *source, PyObject *globals,
11051121
Py_TYPE(locals)->tp_name);
11061122
goto error;
11071123
}
1108-
int r = PyDict_Contains(globals, &_Py_ID(__builtins__));
1109-
if (r == 0) {
1110-
r = PyDict_SetItem(globals, &_Py_ID(__builtins__), PyEval_GetBuiltins());
1111-
}
1112-
if (r < 0) {
1124+
1125+
if (_PyEval_EnsureBuiltins(tstate, globals, 0, NULL) < 0) {
11131126
goto error;
11141127
}
11151128

@@ -1186,11 +1199,13 @@ builtin_exec_impl(PyObject *module, PyObject *source, PyObject *globals,
11861199
}
11871200
if (v == NULL)
11881201
goto error;
1202+
Py_DECREF(globals);
11891203
Py_DECREF(locals);
11901204
Py_DECREF(v);
11911205
Py_RETURN_NONE;
11921206

11931207
error:
1208+
Py_XDECREF(globals);
11941209
Py_XDECREF(locals);
11951210
return NULL;
11961211
}
@@ -1240,10 +1255,12 @@ static PyObject *
12401255
builtin_globals_impl(PyObject *module)
12411256
/*[clinic end generated code: output=e5dd1527067b94d2 input=9327576f92bb48ba]*/
12421257
{
1243-
PyObject *d;
1244-
1245-
d = PyEval_GetGlobals();
1246-
return Py_XNewRef(d);
1258+
if (_PyEval_GetFrame() != NULL) {
1259+
PyObject *globals = PyEval_GetGlobals();
1260+
assert(globals != NULL);
1261+
return Py_NewRef(globals);
1262+
}
1263+
Py_RETURN_NONE;
12471264
}
12481265

12491266

@@ -1887,7 +1904,13 @@ static PyObject *
18871904
builtin_locals_impl(PyObject *module)
18881905
/*[clinic end generated code: output=b46c94015ce11448 input=7874018d478d5c4b]*/
18891906
{
1890-
return _PyEval_GetFrameLocals();
1907+
PyObject *locals;
1908+
if (_PyEval_GetFrame() != NULL) {
1909+
locals = _PyEval_GetFrameLocals();
1910+
assert(locals != NULL || PyErr_Occurred());
1911+
return locals;
1912+
}
1913+
Py_RETURN_NONE;
18911914
}
18921915

18931916

Python/ceval.c

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2746,17 +2746,61 @@ _PyEval_GetFrameLocals(void)
27462746
return locals;
27472747
}
27482748

2749-
PyObject *
2750-
PyEval_GetGlobals(void)
2749+
static PyObject *
2750+
_PyEval_GetGlobals(PyThreadState *tstate)
27512751
{
2752-
PyThreadState *tstate = _PyThreadState_GET();
27532752
_PyInterpreterFrame *current_frame = _PyThreadState_GetFrame(tstate);
27542753
if (current_frame == NULL) {
27552754
return NULL;
27562755
}
27572756
return current_frame->f_globals;
27582757
}
27592758

2759+
PyObject *
2760+
PyEval_GetGlobals(void)
2761+
{
2762+
PyThreadState *tstate = _PyThreadState_GET();
2763+
return _PyEval_GetGlobals(tstate);
2764+
}
2765+
2766+
int
2767+
_PyEval_EnsureBuiltins(PyThreadState *tstate, PyObject *globals, int usemod,
2768+
PyObject **p_builtins)
2769+
{
2770+
PyObject *builtins = NULL;
2771+
if (PyMapping_GetOptionalItem(globals, &_Py_ID(__builtins__), &builtins) < 0) {
2772+
return -1;
2773+
}
2774+
if (builtins == NULL) {
2775+
if (usemod) {
2776+
builtins =
2777+
PyImport_ImportModuleLevel("builtins", NULL, NULL, NULL, 0);
2778+
if (builtins == NULL) {
2779+
return -1;
2780+
}
2781+
}
2782+
else {
2783+
builtins = PyEval_GetBuiltins();
2784+
if (builtins == NULL) {
2785+
assert(_PyErr_Occurred(tstate));
2786+
return -1;
2787+
}
2788+
Py_INCREF(builtins);
2789+
}
2790+
if (PyDict_SetItem(globals, &_Py_ID(__builtins__), builtins) < 0) {
2791+
Py_DECREF(builtins);
2792+
return -1;
2793+
}
2794+
}
2795+
if (p_builtins != NULL) {
2796+
*p_builtins = builtins;
2797+
}
2798+
else {
2799+
Py_DECREF(builtins);
2800+
}
2801+
return 0;
2802+
}
2803+
27602804
PyObject*
27612805
PyEval_GetFrameLocals(void)
27622806
{

Python/import.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3960,25 +3960,28 @@ PyImport_Import(PyObject *module_name)
39603960
}
39613961

39623962
/* Get the builtins from current globals */
3963-
globals = PyEval_GetGlobals();
3963+
globals = PyEval_GetGlobals(); // borrowed
39643964
if (globals != NULL) {
39653965
Py_INCREF(globals);
3966+
// XXX Use _PyEval_EnsureBuiltins()?
39663967
builtins = PyObject_GetItem(globals, &_Py_ID(__builtins__));
39673968
if (builtins == NULL) {
39683969
// XXX Fall back to interp->builtins or sys.modules['builtins']?
39693970
goto err;
39703971
}
39713972
}
3973+
else if (_PyErr_Occurred(tstate)) {
3974+
goto err;
3975+
}
39723976
else {
39733977
/* No globals -- use standard builtins, and fake globals */
3974-
builtins = PyImport_ImportModuleLevel("builtins",
3975-
NULL, NULL, NULL, 0);
3976-
if (builtins == NULL) {
3978+
globals = PyDict_New();
3979+
if (globals == NULL) {
39773980
goto err;
39783981
}
3979-
globals = Py_BuildValue("{OO}", &_Py_ID(__builtins__), builtins);
3980-
if (globals == NULL)
3982+
if (_PyEval_EnsureBuiltins(tstate, globals, 1, &builtins) < 0) {
39813983
goto err;
3984+
}
39823985
}
39833986

39843987
/* Get the __import__ function from the builtins */

0 commit comments

Comments
 (0)