mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-16 22:51:17 +07:00
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
69 lines
1.9 KiB
Python
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()
|