##// END OF EJS Templates
Backport PR #13021: Don't access current_frame f_locals
Matthias Bussonnier -
Show More
@@ -332,7 +332,7 b' class Pdb(OldPdb):'
332 332 if frame in (self.curframe, getattr(self, "initial_frame", None)):
333 333 return False
334 334 else:
335 return frame.f_locals.get("__tracebackhide__", False)
335 return self._get_frame_locals(frame).get("__tracebackhide__", False)
336 336
337 337 return False
338 338
@@ -424,6 +424,28 b' class Pdb(OldPdb):'
424 424 self.shell.hooks.synchronize_with_editor(filename, lineno, 0)
425 425 # vds: <<
426 426
427 def _get_frame_locals(self, frame):
428 """ "
429 Acessing f_local of current frame reset the namespace, so we want to avoid
430 that or the following can happend
431
432 ipdb> foo
433 "old"
434 ipdb> foo = "new"
435 ipdb> foo
436 "new"
437 ipdb> where
438 ipdb> foo
439 "old"
440
441 So if frame is self.current_frame we instead return self.curframe_locals
442
443 """
444 if frame is self.curframe:
445 return self.curframe_locals
446 else:
447 return frame.f_locals
448
427 449 def format_stack_entry(self, frame_lineno, lprefix=': ', context=None):
428 450 if context is None:
429 451 context = self.context
@@ -451,10 +473,11 b' class Pdb(OldPdb):'
451 473 frame, lineno = frame_lineno
452 474
453 475 return_value = ''
454 if '__return__' in frame.f_locals:
455 rv = frame.f_locals['__return__']
456 #return_value += '->'
457 return_value += reprlib.repr(rv) + '\n'
476 loc_frame = self._get_frame_locals(frame)
477 if "__return__" in loc_frame:
478 rv = loc_frame["__return__"]
479 # return_value += '->'
480 return_value += reprlib.repr(rv) + "\n"
458 481 ret.append(return_value)
459 482
460 483 #s = filename + '(' + `lineno` + ')'
@@ -466,10 +489,10 b' class Pdb(OldPdb):'
466 489 else:
467 490 func = "<lambda>"
468 491
469 call = ''
470 if func != '?':
471 if '__args__' in frame.f_locals:
472 args = reprlib.repr(frame.f_locals['__args__'])
492 call = ""
493 if func != "?":
494 if "__args__" in loc_frame:
495 args = reprlib.repr(loc_frame["__args__"])
473 496 else:
474 497 args = '()'
475 498 call = tpl_call % (func, args)
@@ -660,7 +683,7 b' class Pdb(OldPdb):'
660 683
661 684 def getsourcelines(self, obj):
662 685 lines, lineno = inspect.findsource(obj)
663 if inspect.isframe(obj) and obj.f_globals is obj.f_locals:
686 if inspect.isframe(obj) and obj.f_globals is self._get_frame_locals(obj):
664 687 # must be a module frame: do not try to cut a block out of it
665 688 return lines, 1
666 689 elif inspect.ismodule(obj):
@@ -280,14 +280,14 b' def test_xmode_skip():'
280 280
281 281 block = dedent(
282 282 """
283 def f():
284 __tracebackhide__ = True
285 g()
283 def f():
284 __tracebackhide__ = True
285 g()
286 286
287 def g():
288 raise ValueError
287 def g():
288 raise ValueError
289 289
290 f()
290 f()
291 291 """
292 292 )
293 293
@@ -298,15 +298,15 b' f()'
298 298
299 299 block = dedent(
300 300 """
301 def f():
302 __tracebackhide__ = True
303 g()
301 def f():
302 __tracebackhide__ = True
303 g()
304 304
305 def g():
306 from IPython.core.debugger import set_trace
307 set_trace()
305 def g():
306 from IPython.core.debugger import set_trace
307 set_trace()
308 308
309 f()
309 f()
310 310 """
311 311 )
312 312
@@ -324,3 +324,70 b' f()'
324 324 child.expect("ipdb>")
325 325
326 326 child.close()
327
328
329 @skip_win32
330 def test_where_erase_value():
331 """Test that `where` does not access f_locals and erase values."""
332 import pexpect
333
334 env = os.environ.copy()
335 env["IPY_TEST_SIMPLE_PROMPT"] = "1"
336
337 child = pexpect.spawn(
338 sys.executable, ["-m", "IPython", "--colors=nocolor"], env=env
339 )
340 child.timeout = 15 * IPYTHON_TESTING_TIMEOUT_SCALE
341
342 child.expect("IPython")
343 child.expect("\n")
344 child.expect_exact("In [1]")
345
346 block = dedent(
347 """
348 def simple_f():
349 myvar = 1
350 print(myvar)
351 1/0
352 print(myvar)
353 simple_f() """
354 )
355
356 for line in block.splitlines():
357 child.sendline(line)
358 child.expect_exact(line)
359 child.expect_exact("ZeroDivisionError")
360 child.expect_exact("In [2]:")
361
362 child.sendline("%debug")
363
364 ##
365 child.expect("ipdb>")
366
367 child.sendline("myvar")
368 child.expect("1")
369
370 ##
371 child.expect("ipdb>")
372
373 child.sendline("myvar = 2")
374
375 ##
376 child.expect_exact("ipdb>")
377
378 child.sendline("myvar")
379
380 child.expect_exact("2")
381
382 ##
383 child.expect("ipdb>")
384 child.sendline("where")
385
386 ##
387 child.expect("ipdb>")
388 child.sendline("myvar")
389
390 child.expect_exact("2")
391 child.expect("ipdb>")
392
393 child.close()
General Comments 0
You need to be logged in to leave comments. Login now