[3.13] gh-119666: fix multiple class-scope comprehensions referencing __class__ (GH-120295) (#120299)

This commit is contained in:
Miss Islington (bot) 2024-06-10 06:37:28 +02:00 committed by GitHub
parent c15f94d6fb
commit 03cd44759f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 36 additions and 13 deletions

View file

@ -780,22 +780,19 @@ inline_comprehension(PySTEntryObject *ste, PySTEntryObject *comp,
if (existing == NULL && PyErr_Occurred()) {
return 0;
}
// __class__ is never allowed to be free through a class scope (see
// drop_class_free)
if (scope == FREE && ste->ste_type == ClassBlock &&
_PyUnicode_EqualToASCIIString(k, "__class__")) {
scope = GLOBAL_IMPLICIT;
if (PySet_Discard(comp_free, k) < 0) {
return 0;
}
remove_dunder_class = 1;
}
if (!existing) {
// name does not exist in scope, copy from comprehension
assert(scope != FREE || PySet_Contains(comp_free, k) == 1);
if (scope == FREE && ste->ste_type == ClassBlock &&
_PyUnicode_EqualToASCIIString(k, "__class__")) {
// if __class__ is unbound in the enclosing class scope and free
// in the comprehension scope, it needs special handling; just
// letting it be marked as free in class scope will break due to
// drop_class_free
scope = GLOBAL_IMPLICIT;
only_flags &= ~DEF_FREE;
if (PySet_Discard(comp_free, k) < 0) {
return 0;
}
remove_dunder_class = 1;
}
PyObject *v_flags = PyLong_FromLong(only_flags);
if (v_flags == NULL) {
return 0;