Issue 24959: unittest swallows part of stack trace when raising AssertionError in a TestCase (original) (raw)

Issue24959

Created on 2015-08-29 16:15 by chris.jerdonek, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 23688 merged iritkatriel,2021-04-09 13:31
PR 31775 merged miss-islington,2022-03-08 21:43
PR 31776 merged iritkatriel,2022-03-08 21:56
Messages (11)
msg249323 - (view) Author: Chris Jerdonek (chris.jerdonek) * (Python committer) Date: 2015-08-29 16:15
unittest swallows some lines of the stack trace when raising an AssertionError using the "raise from" syntax inside a TestCase. This marks it harder to pinpoint the source of test failures. It is also confusing to see a stack trace like this because the error doesn't originate where the stack trace says it originates. To reproduce: import unittest def foo(): raise Exception("foo") class Test(unittest.TestCase): def test_not_okay(self): try: foo() except Exception as exc: raise AssertionError("bar") from exc def test_okay1(self): try: foo() except Exception as exc: raise ValueError("bar") from exc def test_okay2(self): try: foo() except Exception as exc: raise Exception("bar") from exc The result (observe how the display for "test_not_okay" differs from the other two): ====================================================================== ERROR: test_okay1 (error.Test) ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/chris/dev/error.py", line 17, in test_okay1 foo() File "/Users/chris/dev/error.py", line 5, in foo raise Exception("foo") Exception: foo The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/Users/chris/dev/error.py", line 19, in test_okay1 raise ValueError("bar") from exc ValueError: bar ====================================================================== ERROR: test_okay2 (error.Test) ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/chris/dev/error.py", line 23, in test_okay2 foo() File "/Users/chris/dev/error.py", line 5, in foo raise Exception("foo") Exception: foo The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/Users/chris/dev/error.py", line 25, in test_okay2 raise Exception("bar") from exc Exception: bar ====================================================================== FAIL: test_not_okay (error.Test) ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/chris/dev/error.py", line 11, in test_not_okay foo() Exception: foo The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/Users/chris/dev/error.py", line 13, in test_not_okay raise AssertionError("bar") from exc AssertionError: bar ---------------------------------------------------------------------- Ran 3 tests in 0.001s FAILED (failures=1, errors=2)
msg249324 - (view) Author: Chris Jerdonek (chris.jerdonek) * (Python committer) Date: 2015-08-29 16:26
I guess this isn't limited just to the "raise from" syntax. It also occurs if "from exc" is removed from the example above.
msg261719 - (view) Author: Robert Collins (rbcollins) * (Python committer) Date: 2016-03-14 03:07
Hmm, this is a little surprising, but - why are you raising AssertionError like that - thats what assertRaises is for.
msg261847 - (view) Author: Chris Jerdonek (chris.jerdonek) * (Python committer) Date: 2016-03-16 10:07
This is simply a reduced test case to illustrate the issue more clearly. There was more to it in how I was using it in practice.
msg261856 - (view) Author: Robert Collins (rbcollins) * (Python committer) Date: 2016-03-16 18:22
I'm fairly sure its eating the stack frames because the calling frames are annotated __unittest__ - its technically a feature :/.
msg261857 - (view) Author: Robert Collins (rbcollins) * (Python committer) Date: 2016-03-16 18:35
Yes, it is... ish. The frame skipping code occurs when we serialise exceptions, and we pass a limit in. The limit is calculated on the main exception only. If the cause has a longer exception than the limit we calculated, you'd see this behaviour. Probably need to make it possible to do per-exception processing of limit: I think via a callback or similar mechanism in traceback (because the cause might have thrown from some code that is also marked __unittest, so if we're honouring that, we should honour it within each exception.
msg269782 - (view) Author: Aaron Sokoloski (Aaron Sokoloski) Date: 2016-07-04 11:29
I've run into this bug too. Took a while to track down the cause :)
msg382895 - (view) Author: Irit Katriel (iritkatriel) * (Python committer) Date: 2020-12-12 01:00
I think this is the same as , where I've recently attached a patch that removes __unittest frames from the traceback rather than count them and then set a limit for printing. I could add to that patch what Robert suggests here - to filter the __cause__ traceback as well.
msg414778 - (view) Author: Irit Katriel (iritkatriel) * (Python committer) Date: 2022-03-08 21:44
New changeset 88b7d86a73da9388aa65c96401c2984c8c16f8db by Irit Katriel in branch 'main': bpo-24959: fix unittest.assertRaises bug where traceback entries are dropped from chained exceptions (GH-23688) https://github.com/python/cpython/commit/88b7d86a73da9388aa65c96401c2984c8c16f8db
msg414779 - (view) Author: miss-islington (miss-islington) Date: 2022-03-08 22:09
New changeset 26fa25a9a73f0e31bf0f0d94103fa4de38c0a3cc by Miss Islington (bot) in branch '3.10': bpo-24959: fix unittest.assertRaises bug where traceback entries are dropped from chained exceptions (GH-23688) https://github.com/python/cpython/commit/26fa25a9a73f0e31bf0f0d94103fa4de38c0a3cc
msg414781 - (view) Author: Irit Katriel (iritkatriel) * (Python committer) Date: 2022-03-08 23:01
New changeset f3ea249569bbce8417c55d421521bb672c202552 by Irit Katriel in branch '3.9': bpo-24959: fix unittest.assertRaises bug where traceback entries are dropped from chained exceptions (GH-23688) (GH-31776) https://github.com/python/cpython/commit/f3ea249569bbce8417c55d421521bb672c202552
History
Date User Action Args
2022-04-11 14:58:20 admin set github: 69147
2022-03-08 23:03:00 iritkatriel set status: open -> closedstage: patch review -> resolvedresolution: fixedversions: + Python 3.11, - Python 3.8
2022-03-08 23:01:05 iritkatriel set messages: +
2022-03-08 22:09:32 miss-islington set messages: +
2022-03-08 21:56:33 iritkatriel set pull_requests: + <pull%5Frequest29883>
2022-03-08 21:44:03 iritkatriel set messages: +
2022-03-08 21:43:59 miss-islington set nosy: + miss-islingtonpull_requests: + <pull%5Frequest29882>
2021-06-02 14:06:41 iritkatriel link issue44280 superseder
2021-04-09 17:54:41 dseomn set nosy: + dseomn
2021-04-09 13:31:56 iritkatriel link issue42247 superseder
2021-04-09 13:31:16 iritkatriel set keywords: + patchstage: test needed -> patch reviewpull_requests: + <pull%5Frequest24039>
2021-04-09 13:26:49 iritkatriel link issue37712 superseder
2020-12-12 01:00:01 iritkatriel set nosy: + iritkatrielmessages: + versions: + Python 3.8, Python 3.9, Python 3.10, - Python 3.5, Python 3.6
2016-07-04 11:29:32 Aaron Sokoloski set nosy: + Aaron Sokoloskimessages: +
2016-03-16 18:52:42 rbcollins set stage: needs patch -> test needed
2016-03-16 18:35:16 rbcollins set messages: + title: unittest swallows par t of stack trace when raising AssertionError in a TestCase -> unittest swallows part of stack trace when raising AssertionError in a TestCase
2016-03-16 18:22:50 rbcollins set messages: + title: unittest swallows part of stack trace when raising AssertionError in a TestCase -> unittest swallows par t of stack trace when raising AssertionError in a TestCase
2016-03-16 10:07:23 chris.jerdonek set messages: +
2016-03-14 03:07:09 rbcollins set messages: + stage: needs patch
2016-01-04 00🔞15 ezio.melotti set nosy: + rbcollins, ezio.melotti, michael.foordversions: + Python 3.5, Python 3.6, - Python 3.4
2015-08-29 16:26:13 chris.jerdonek set messages: + title: unittest swallows part of stack trace using "raise from" with AssertionError -> unittest swallows part of stack trace when raising AssertionError in a TestCase
2015-08-29 16:15:14 chris.jerdonek create