mirror of
https://github.com/python/cpython.git
synced 2025-12-31 04:23:37 +00:00
[3.12] gh-130809: Fix PyFrame_LocalsToFast copying the wrong value (#130816)
* gh-130809: Fix `PyFrame_LocalsToFast` copying the wrong value * Skip hidden locals * test, blurb * Update Misc/NEWS.d/next/Core_and_Builtins/2025-03-04-12-52-21.gh-issue-130809.fSXq60.rst Co-authored-by: Tian Gao <gaogaotiantian@hotmail.com> * Update test * PR feedback * formatting * comment --------- Co-authored-by: Tian Gao <gaogaotiantian@hotmail.com>
This commit is contained in:
parent
fcf1f57d91
commit
33605da91c
3 changed files with 22 additions and 0 deletions
|
|
@ -709,6 +709,23 @@ def test_multiple_comprehension_name_reuse(self):
|
|||
self._check_in_scopes(code, {"x": 2, "y": [3]}, ns={"x": 3}, scopes=["class"])
|
||||
self._check_in_scopes(code, {"x": 2, "y": [2]}, ns={"x": 3}, scopes=["function", "module"])
|
||||
|
||||
def test_name_collision_locals(self):
|
||||
# GH-130809: The existence of a hidden fast from list comprehension
|
||||
# should not cause frame.f_locals on module level to return a new dict
|
||||
# every time it is accessed.
|
||||
|
||||
code = """
|
||||
import sys
|
||||
frame = sys._getframe()
|
||||
f_locals = frame.f_locals
|
||||
foo = 1
|
||||
[foo for foo in [0]]
|
||||
# calls _PyFrame_LocalsToFast which triggers the issue
|
||||
from abc import *
|
||||
same_f_locals = frame.f_locals is f_locals
|
||||
"""
|
||||
self._check_in_scopes(code, {"foo": 1, "same_f_locals": True}, scopes=["module"])
|
||||
|
||||
def test_exception_locations(self):
|
||||
# The location of an exception raised from __init__ or
|
||||
# __next__ should should be the iterator expression
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
Fixed an issue where ``_PyFrame_LocalsToFast`` tries to write module level
|
||||
values to hidden fasts.
|
||||
|
|
@ -1405,6 +1405,9 @@ _PyFrame_LocalsToFast(_PyInterpreterFrame *frame, int clear)
|
|||
if (kind & CO_FAST_FREE && !(co->co_flags & CO_OPTIMIZED)) {
|
||||
continue;
|
||||
}
|
||||
if (kind & CO_FAST_HIDDEN) {
|
||||
continue;
|
||||
}
|
||||
PyObject *name = PyTuple_GET_ITEM(co->co_localsplusnames, i);
|
||||
PyObject *value = PyObject_GetItem(locals, name);
|
||||
/* We only care about NULLs if clear is true. */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue