Don't call frame.f_locals multiple times when assigning locals after evaluation. Fixes #915

This commit is contained in:
Fabio Zadrozny 2022-04-21 16:16:59 -03:00
parent 7be59933b1
commit 6174f4c4bd
2 changed files with 22 additions and 4 deletions

View file

@ -377,13 +377,17 @@ def _update_globals_and_locals(updated_globals, initial_globals, frame):
# Still, the approach to have a single namespace was chosen because it was the only
# one that enabled creating and using variables during the same evaluation.
assert updated_globals is not None
changed = False
f_locals = None
for key, val in updated_globals.items():
if initial_globals.get(key) is not val:
changed = True
frame.f_locals[key] = val
if f_locals is None:
# Note: we call f_locals only once because each time
# we call it the values may be reset.
f_locals = frame.f_locals
if changed:
f_locals[key] = val
if f_locals is not None:
pydevd_save_locals.save_locals(frame)

View file

@ -9,6 +9,8 @@ global_frame = sys._getframe()
def obtain_frame():
A = 1
B = 2
yield sys._getframe()
@ -116,3 +118,15 @@ def test_evaluate_expression_4(disable_critical_log):
assert 'email' in sys._getframe().f_globals
del sys._getframe().f_globals['email']
assert 'email' not in sys._getframe().f_globals
def test_evaluate_expression_5(disable_critical_log):
from _pydevd_bundle.pydevd_vars import evaluate_expression
def check(frame):
eval_txt = 'A, B = 5, 6'
evaluate_expression(None, frame, eval_txt, is_exec=True)
assert frame.f_locals['A'] == 5
assert frame.f_locals['B'] == 6
check(next(iter(obtain_frame())))