Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

gh-106670: Allow Pdb to move between chained exceptions#106676

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
iritkatriel merged 12 commits intopython:mainfromCarreau:gh-106670
Aug 28, 2023
Merged
Changes from1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
PrevPrevious commit
NextNext commit
Move the exception logic to its own function.
Also move the release of the list of exception to a context managerfor security
  • Loading branch information
@Carreau
Carreau committedAug 16, 2023
commit920af940498200f773cef2f5f68e74f968dcfdd8
75 changes: 51 additions & 24 deletionsLib/pdb.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -85,6 +85,7 @@
import traceback
import linecache

from contextlib import contextmanager
from typing import Union


Expand DownExpand Up@@ -418,13 +419,19 @@ def preloop(self):
self.message('display %s: %r [old: %r]' %
(expr, newvalue, oldvalue))

def interaction(self, frame, tb_or_exc):
# Restore the previous signal handler at the Pdb prompt.
def _get_tb_and_exceptions(self, tb_or_exc):
"""
Given a tracecack or an exception, return a tuple of chained exceptions
and current traceback to inspect.

This will deal with selecting the right ``__cause__`` or ``__context__``
as well as handling cycles, and return a flattened list of exceptions we
can jump to with do_exceptions.

"""
_exceptions = []
if isinstance(tb_or_exc, BaseException):
traceback, exception = tb_or_exc.__traceback__, tb_or_exc
current = exception
traceback, current = tb_or_exc.__traceback__, tb_or_exc

while current is not None:
if current in _exceptions:
Expand All@@ -446,29 +453,49 @@ def interaction(self, frame, tb_or_exc):
break
else:
traceback = tb_or_exc
self._chained_exceptions = tuple(reversed(_exceptions))
self._chained_exception_index = len(_exceptions) - 1
return tuple(reversed(_exceptions)), traceback

if Pdb._previous_sigint_handler:
try:
signal.signal(signal.SIGINT, Pdb._previous_sigint_handler)
except ValueError: # ValueError: signal only works in main thread
pass
else:
Pdb._previous_sigint_handler = None
if self.setup(frame, traceback):
# no interaction desired at this time (happens if .pdbrc contains
# a command like "continue")
@contextmanager
def _hold_exceptions(self, exceptions):
"""
Context manager to ensure proper cleaning of exceptions references

When given a chained exception instead of a traceback,
pdb may hold references to many objects which may leak memory.

We use this context manager to make sure everything is properly cleaned

"""
try:
self._chained_exceptions = exceptions
self._chained_exception_index = len(exceptions) - 1
yield
finally:
# we can't put those in forget as otherwise they would
# be cleared on exception change
self._chained_exceptions = tuple()
self._chained_exception_index = 0

def interaction(self, frame, tb_or_exc):
# Restore the previous signal handler at the Pdb prompt.
_chained_exceptions, tb = self._get_tb_and_exceptions(tb_or_exc)
with self._hold_exceptions(_chained_exceptions):
if Pdb._previous_sigint_handler:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Does this need to be inside the _hold_exceptions() block?

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Does not need to, I reduced the spam of the context manager.

try:
signal.signal(signal.SIGINT, Pdb._previous_sigint_handler)
except ValueError: # ValueError: signal only works in main thread
pass
else:
Pdb._previous_sigint_handler = None
if self.setup(frame, tb):
# no interaction desired at this time (happens if .pdbrc contains
# a command like "continue")
self.forget()
return
self.print_stack_entry(self.stack[self.curindex])
self._cmdloop()
self.forget()
return
self.print_stack_entry(self.stack[self.curindex])
self._cmdloop()
self.forget()

# we can't put those in forget as otherwise they would
# be cleared on exception change
self._chained_exceptions = tuple()
self._chained_exception_index = 0

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

We should keep the single line between methods.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Done.


def displayhook(self, obj):
Expand Down

[8]ページ先頭

©2009-2025 Movatter.jp