Files
openide/python/helpers/pydev/_pydevd_bundle/pydevd_save_locals.py
Andrey Lisin eb956ca29d PY-38378 PY-38424 Fix updating variables in debugger console
We now access the `frame.f_locals` attribute only once. Multiple access leads to the loss of the changes we have made. We also alter the second argument of the `PyFrame_LocalsToFast()` to 1 to ensure that all the deleted variables will be wiped out from the frame locals.

(cherry picked from commit 28abff39b2c37f30651db220e8700032a629ce73)

GitOrigin-RevId: 8514da7ec187c1192ea9cdf851f89f008242fc30
2019-11-25 09:31:23 +00:00

69 lines
1.9 KiB
Python

"""
Utility for saving locals.
"""
import sys
try:
import types
frame_type = types.FrameType
except:
frame_type = type(sys._getframe())
def is_save_locals_available():
return save_locals_impl is not None
def save_locals(frame):
"""
Copy values from locals_dict into the fast stack slots in the given frame.
Note: the 'save_locals' branch had a different approach wrapping the frame (much more code, but it gives ideas
on how to save things partially, not the 'whole' locals).
"""
if not isinstance(frame, frame_type):
# Fix exception when changing Django variable (receiving DjangoTemplateFrame)
return
if save_locals_impl is not None:
try:
save_locals_impl(frame)
except:
pass
def make_save_locals_impl():
"""
Factory for the 'save_locals_impl' method. This may seem like a complicated pattern but it is essential that the method is created at
module load time. Inner imports after module load time would cause an occasional debugger deadlock due to the importer lock and debugger
lock being taken in different order in different threads.
"""
try:
if '__pypy__' in sys.builtin_module_names:
import __pypy__ # @UnresolvedImport
pypy_locals_to_fast = __pypy__.locals_to_fast
except:
pass
else:
if '__pypy__' in sys.builtin_module_names:
def save_locals_pypy_impl(frame):
pypy_locals_to_fast(frame)
return save_locals_pypy_impl
try:
import ctypes
locals_to_fast = ctypes.pythonapi.PyFrame_LocalsToFast
except:
pass
else:
def save_locals_ctypes_impl(frame):
locals_to_fast(ctypes.py_object(frame), ctypes.c_int(1))
return save_locals_ctypes_impl
return None
save_locals_impl = make_save_locals_impl()