mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Make -P
(pdb) work better with exceptions triggered from events
Previously, if an exception was raised from an event listener, and the `-P` option was specified, the debugger would be started not for the original error but for the `ExtensionError` wrapping it that was raised by `EventManager.emit`. That made it difficult to debug the error. With this change, when `-P` is specified, wrapping of errors in `ExtensionError` is disabled, which allows pdb to debug the original error.
This commit is contained in:
parent
7e76f2c307
commit
66f9ee4afd
1
CHANGES
1
CHANGES
@ -30,6 +30,7 @@ Features added
|
||||
Bugs fixed
|
||||
----------
|
||||
|
||||
* #10634: Make -P (pdb) option work better with exceptions triggered from events
|
||||
* #10031: py domain: Fix spurious whitespace in unparsing various operators (``+``,
|
||||
``-``, ``~``, and ``**``). Patch by Adam Turner.
|
||||
* #10460: logging: Always show node source locations as absolute paths.
|
||||
|
@ -131,7 +131,8 @@ class Sphinx:
|
||||
buildername: str, confoverrides: Dict = None,
|
||||
status: Optional[IO] = sys.stdout, warning: Optional[IO] = sys.stderr,
|
||||
freshenv: bool = False, warningiserror: bool = False, tags: List[str] = None,
|
||||
verbosity: int = 0, parallel: int = 0, keep_going: bool = False) -> None:
|
||||
verbosity: int = 0, parallel: int = 0, keep_going: bool = False,
|
||||
pdb: bool = False) -> None:
|
||||
self.phase = BuildPhase.INITIALIZATION
|
||||
self.verbosity = verbosity
|
||||
self.extensions: Dict[str, Extension] = {}
|
||||
@ -173,6 +174,7 @@ class Sphinx:
|
||||
self.warningiserror = False
|
||||
else:
|
||||
self.warningiserror = warningiserror
|
||||
self.pdb = pdb
|
||||
logging.setup(self, self._status, self._warning)
|
||||
|
||||
self.events = EventManager(self)
|
||||
|
@ -272,7 +272,8 @@ def build_main(argv: List[str] = sys.argv[1:]) -> int:
|
||||
app = Sphinx(args.sourcedir, args.confdir, args.outputdir,
|
||||
args.doctreedir, args.builder, confoverrides, status,
|
||||
warning, args.freshenv, args.warningiserror,
|
||||
args.tags, args.verbosity, args.jobs, args.keep_going)
|
||||
args.tags, args.verbosity, args.jobs, args.keep_going,
|
||||
args.pdb)
|
||||
app.build(args.force_all, filenames)
|
||||
return app.statuscode
|
||||
except (Exception, KeyboardInterrupt) as exc:
|
||||
|
@ -98,6 +98,9 @@ class EventManager:
|
||||
except SphinxError:
|
||||
raise
|
||||
except Exception as exc:
|
||||
if self.app.pdb:
|
||||
# Just pass through the error, so that it can be debugged.
|
||||
raise
|
||||
modname = safe_getattr(listener.handler, '__module__', None)
|
||||
raise ExtensionError(__("Handler %r for event %r threw an exception") %
|
||||
(listener.handler, name), exc, modname=modname) from exc
|
||||
|
@ -19,11 +19,16 @@ def test_event_priority():
|
||||
assert result == [3, 1, 2, 5, 4]
|
||||
|
||||
|
||||
class FakeApp:
|
||||
def __init__(self, pdb: bool = False):
|
||||
self.pdb = pdb
|
||||
|
||||
|
||||
def test_event_allowed_exceptions():
|
||||
def raise_error(app):
|
||||
raise RuntimeError
|
||||
|
||||
events = EventManager(object()) # pass an dummy object as an app
|
||||
events = EventManager(FakeApp()) # pass an dummy object as an app
|
||||
events.connect('builder-inited', raise_error, priority=500)
|
||||
|
||||
# all errors are converted to ExtensionError
|
||||
@ -33,3 +38,19 @@ def test_event_allowed_exceptions():
|
||||
# Allow RuntimeError (pass-through)
|
||||
with pytest.raises(RuntimeError):
|
||||
events.emit('builder-inited', allowed_exceptions=(RuntimeError,))
|
||||
|
||||
|
||||
def test_event_pdb():
|
||||
def raise_error(app):
|
||||
raise RuntimeError
|
||||
|
||||
events = EventManager(FakeApp(pdb=True)) # pass an dummy object as an app
|
||||
events.connect('builder-inited', raise_error, priority=500)
|
||||
|
||||
# errors aren't converted
|
||||
with pytest.raises(RuntimeError):
|
||||
events.emit('builder-inited')
|
||||
|
||||
# Allow RuntimeError (pass-through)
|
||||
with pytest.raises(RuntimeError):
|
||||
events.emit('builder-inited', allowed_exceptions=(RuntimeError,))
|
||||
|
Loading…
Reference in New Issue
Block a user