[3.13] gh-119821: Support non-dict globals in LOAD_FROM_DICT_OR_GLOBALS (#119822) (#119889)

dSupport non-dict globals in LOAD_FROM_DICT_OR_GLOBALS

The implementation basically copies LOAD_GLOBAL. Possibly it could be deduplicated,
but that seems like it may get hairy since the two operations have different operands.

This is important to fix in 3.14 for PEP 649, but it's a bug in earlier versions too,
and we should backport to 3.13 and 3.12 if possible.

(cherry picked from commit 80a4e38994)
This commit is contained in:
Jelle Zijlstra 2024-05-31 21:56:26 -07:00 committed by GitHub
parent 0a266f7e74
commit a0559849ac
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 76 additions and 59 deletions

View file

@ -1375,18 +1375,35 @@ dummy_func(
ERROR_NO_POP();
}
if (v == NULL) {
if (PyDict_GetItemRef(GLOBALS(), name, &v) < 0) {
ERROR_NO_POP();
}
if (v == NULL) {
if (PyMapping_GetOptionalItem(BUILTINS(), name, &v) < 0) {
if (PyDict_CheckExact(GLOBALS())
&& PyDict_CheckExact(BUILTINS()))
{
v = _PyDict_LoadGlobal((PyDictObject *)GLOBALS(),
(PyDictObject *)BUILTINS(),
name);
if (v == NULL) {
if (!_PyErr_Occurred(tstate)) {
/* _PyDict_LoadGlobal() returns NULL without raising
* an exception if the key doesn't exist */
_PyEval_FormatExcCheckArg(tstate, PyExc_NameError,
NAME_ERROR_MSG, name);
}
ERROR_NO_POP();
}
}
else {
/* Slow-path if globals or builtins is not a dict */
/* namespace 1: globals */
ERROR_IF(PyMapping_GetOptionalItem(GLOBALS(), name, &v) < 0, error);
if (v == NULL) {
_PyEval_FormatExcCheckArg(
tstate, PyExc_NameError,
NAME_ERROR_MSG, name);
ERROR_NO_POP();
/* namespace 2: builtins */
ERROR_IF(PyMapping_GetOptionalItem(BUILTINS(), name, &v) < 0, error);
if (v == NULL) {
_PyEval_FormatExcCheckArg(
tstate, PyExc_NameError,
NAME_ERROR_MSG, name);
ERROR_IF(true, error);
}
}
}
}