Skip to content

Commit 978b315

Browse files
committed
Simplify some exception handling code
Mostly avoid unnecessary usage of sys.exc_info(). Since Python3, exception objects themselves have all that's needed. They are also easier to type.
1 parent fcd3fad commit 978b315

File tree

5 files changed

+32
-43
lines changed

5 files changed

+32
-43
lines changed

src/_pytest/config/__init__.py

+3-7
Original file line numberDiff line numberDiff line change
@@ -612,13 +612,9 @@ def import_plugin(self, modname, consider_entry_points=False):
612612
try:
613613
__import__(importspec)
614614
except ImportError as e:
615-
new_exc_message = 'Error importing plugin "{}": {}'.format(
616-
modname, str(e.args[0])
617-
)
618-
new_exc = ImportError(new_exc_message)
619-
tb = sys.exc_info()[2]
620-
621-
raise new_exc.with_traceback(tb)
615+
raise ImportError(
616+
'Error importing plugin "{}": {}'.format(modname, str(e.args[0]))
617+
).with_traceback(e.__traceback__)
622618

623619
except Skipped as e:
624620
from _pytest.warnings import _issue_warning_captured

src/_pytest/fixtures.py

+8-8
Original file line numberDiff line numberDiff line change
@@ -862,19 +862,19 @@ def addfinalizer(self, finalizer):
862862
self._finalizers.append(finalizer)
863863

864864
def finish(self, request):
865-
exceptions = []
865+
exc = None
866866
try:
867867
while self._finalizers:
868868
try:
869869
func = self._finalizers.pop()
870870
func()
871-
except: # noqa
872-
exceptions.append(sys.exc_info())
873-
if exceptions:
874-
_, val, tb = exceptions[0]
875-
# Ensure to not keep frame references through traceback.
876-
del exceptions
877-
raise val.with_traceback(tb)
871+
except BaseException as e:
872+
# XXX Only first exception will be seen by user,
873+
# ideally all should be reported.
874+
if exc is None:
875+
exc = e
876+
if exc:
877+
raise exc
878878
finally:
879879
hook = self._fixturemanager.session.gethookproxy(request.node.fspath)
880880
hook.pytest_fixture_post_finalizer(fixturedef=self, request=request)

src/_pytest/main.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -496,11 +496,11 @@ def collect(self):
496496
self.trace.root.indent += 1
497497
try:
498498
yield from self._collect(fspath, parts)
499-
except NoMatch:
499+
except NoMatch as exc:
500500
report_arg = "::".join((str(fspath), *parts))
501501
# we are inside a make_report hook so
502502
# we cannot directly pass through the exception
503-
self._notfound.append((report_arg, sys.exc_info()[1]))
503+
self._notfound.append((report_arg, exc))
504504

505505
self.trace.root.indent -= 1
506506
self._collection_node_cache1.clear()

src/_pytest/python.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -516,8 +516,7 @@ def _importtestmodule(self):
516516
mod = self.fspath.pyimport(ensuresyspath=importmode)
517517
except SyntaxError:
518518
raise self.CollectError(ExceptionInfo.from_current().getrepr(style="short"))
519-
except self.fspath.ImportMismatchError:
520-
e = sys.exc_info()[1]
519+
except self.fspath.ImportMismatchError as e:
521520
raise self.CollectError(
522521
"import file mismatch:\n"
523522
"imported module %r has this __file__ attribute:\n"

src/_pytest/runner.py

+18-24
Original file line numberDiff line numberDiff line change
@@ -133,16 +133,14 @@ def pytest_runtest_call(item):
133133
pass
134134
try:
135135
item.runtest()
136-
except Exception:
136+
except Exception as e:
137137
# Store trace info to allow postmortem debugging
138-
type, value, tb = sys.exc_info()
139-
assert tb is not None
140-
tb = tb.tb_next # Skip *this* frame
141-
sys.last_type = type
142-
sys.last_value = value
143-
sys.last_traceback = tb
144-
del type, value, tb # Get rid of these in this frame
145-
raise
138+
sys.last_type = type(e)
139+
sys.last_value = e
140+
assert e.__traceback__ is not None
141+
# Skip *this* frame
142+
sys.last_traceback = e.__traceback__.tb_next
143+
raise e
146144

147145

148146
def pytest_runtest_teardown(item, nextitem):
@@ -318,15 +316,13 @@ def _callfinalizers(self, colitem):
318316
fin = finalizers.pop()
319317
try:
320318
fin()
321-
except TEST_OUTCOME:
319+
except TEST_OUTCOME as e:
322320
# XXX Only first exception will be seen by user,
323321
# ideally all should be reported.
324322
if exc is None:
325-
exc = sys.exc_info()
323+
exc = e
326324
if exc:
327-
_, val, tb = exc
328-
assert val is not None
329-
raise val.with_traceback(tb)
325+
raise exc
330326

331327
def _teardown_with_finalization(self, colitem):
332328
self._callfinalizers(colitem)
@@ -352,15 +348,13 @@ def _teardown_towards(self, needed_collectors):
352348
break
353349
try:
354350
self._pop_and_teardown()
355-
except TEST_OUTCOME:
351+
except TEST_OUTCOME as e:
356352
# XXX Only first exception will be seen by user,
357353
# ideally all should be reported.
358354
if exc is None:
359-
exc = sys.exc_info()
355+
exc = e
360356
if exc:
361-
_, val, tb = exc
362-
assert val is not None
363-
raise val.with_traceback(tb)
357+
raise exc
364358

365359
def prepare(self, colitem):
366360
""" setup objects along the collector chain to the test-method
@@ -371,15 +365,15 @@ def prepare(self, colitem):
371365
# check if the last collection node has raised an error
372366
for col in self.stack:
373367
if hasattr(col, "_prepare_exc"):
374-
_, val, tb = col._prepare_exc
375-
raise val.with_traceback(tb)
368+
exc = col._prepare_exc
369+
raise exc
376370
for col in needed_collectors[len(self.stack) :]:
377371
self.stack.append(col)
378372
try:
379373
col.setup()
380-
except TEST_OUTCOME:
381-
col._prepare_exc = sys.exc_info()
382-
raise
374+
except TEST_OUTCOME as e:
375+
col._prepare_exc = e
376+
raise e
383377

384378

385379
def collect_one_node(collector):

0 commit comments

Comments
 (0)