mirror of
https://github.com/microsoft/debugpy.git
synced 2025-12-23 08:48:12 +00:00
Ensure that f_locals mutation is propagated to actual locals.
This commit is contained in:
parent
dfd61c8e72
commit
1d4e23b328
2 changed files with 20 additions and 10 deletions
|
|
@ -231,7 +231,7 @@ class Adapter:
|
|||
raise request.isnt_valid(
|
||||
f"Unsupported exception breakpoint filter: {filter!r}"
|
||||
)
|
||||
|
||||
|
||||
break_mode = ExceptionBreakMode.NEVER
|
||||
if "raised" in filters:
|
||||
break_mode = ExceptionBreakMode.ALWAYS
|
||||
|
|
@ -391,7 +391,7 @@ class Adapter:
|
|||
raise request.isnt_valid(f'Unknown thread with "threadId":{thread_id}')
|
||||
self._tracer.step_over(thread)
|
||||
return {}
|
||||
|
||||
|
||||
def exceptionInfo_request(self, request: Request):
|
||||
thread_id = request("threadId", int)
|
||||
thread = Thread.get(thread_id)
|
||||
|
|
@ -399,7 +399,9 @@ class Adapter:
|
|||
raise request.isnt_valid(f'Unknown thread with "threadId":{thread_id}')
|
||||
exc_info = thread.current_exception
|
||||
if exc_info is None:
|
||||
raise request.cant_handle(f'No current exception on thread with "threadId":{thread_id}')
|
||||
raise request.cant_handle(
|
||||
f'No current exception on thread with "threadId":{thread_id}'
|
||||
)
|
||||
return exc_info.__getstate__()
|
||||
|
||||
def scopes_request(self, request: Request):
|
||||
|
|
@ -430,7 +432,7 @@ class Adapter:
|
|||
except BaseException as exc:
|
||||
result = exc
|
||||
return eval.Result(frame, result)
|
||||
|
||||
|
||||
def setVariable_request(self, request: Request):
|
||||
name = request("name", str)
|
||||
value = request("value", str)
|
||||
|
|
@ -442,7 +444,7 @@ class Adapter:
|
|||
return container.set_variable(name, value)
|
||||
except BaseException as exc:
|
||||
raise request.cant_handle(str(exc))
|
||||
|
||||
|
||||
def setExpression_request(self, request: Request):
|
||||
expr = request("expression", str)
|
||||
value = request("value", str)
|
||||
|
|
@ -456,7 +458,7 @@ class Adapter:
|
|||
except BaseException as exc:
|
||||
raise request.cant_handle(str(exc))
|
||||
return eval.Result(frame, result)
|
||||
|
||||
|
||||
def disconnect_request(self, request: Request):
|
||||
Breakpoint.clear()
|
||||
self._tracer.abandon_step()
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@
|
|||
# Licensed under the MIT License. See LICENSE in the project root
|
||||
# for license information.
|
||||
|
||||
import ctypes
|
||||
import debugpy
|
||||
import threading
|
||||
from collections.abc import Iterable
|
||||
from debugpy.server.inspect import inspect
|
||||
from types import FrameType
|
||||
from typing import ClassVar, Dict, Self
|
||||
|
||||
type StackFrame = "debugpy.server.tracing.StackFrame"
|
||||
|
|
@ -102,7 +102,7 @@ class Value(VariableContainer):
|
|||
setattr(self.value, name, value)
|
||||
result = getattr(self.value, name)
|
||||
return Value(self.frame, result)
|
||||
|
||||
|
||||
|
||||
class Result(Value):
|
||||
def __getstate__(self) -> dict[str, object]:
|
||||
|
|
@ -126,8 +126,6 @@ class Variable(Value):
|
|||
|
||||
|
||||
class Scope(Variable):
|
||||
frame: FrameType
|
||||
|
||||
def __init__(self, frame: StackFrame, name: str, storage: dict[str, object]):
|
||||
class ScopeObject:
|
||||
def __dir__(self):
|
||||
|
|
@ -138,5 +136,15 @@ class Scope(Variable):
|
|||
|
||||
def __setattr__(self, name, value):
|
||||
storage[name] = value
|
||||
# Until PEP 667 is implemented, this is necessary to propagate the changes
|
||||
# from the dict to actual locals.
|
||||
try:
|
||||
PyFrame_LocalsToFast = ctypes.pythonapi.PyFrame_LocalsToFast
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
PyFrame_LocalsToFast(
|
||||
ctypes.py_object(frame.frame_object), ctypes.c_int(0)
|
||||
)
|
||||
|
||||
super().__init__(frame, name, ScopeObject())
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue