|
4 | 4 | """ |
5 | 5 |
|
6 | 6 | from __future__ import absolute_import, unicode_literals, print_function |
7 | | -import sys |
| 7 | +import sys, traceback |
8 | 8 | from future.builtins import * |
9 | 9 | from future.utils import (old_div, istext, isbytes, native, PY2, PY3, |
10 | 10 | native_str, raise_, as_native_str, ensure_new_type, |
@@ -314,6 +314,61 @@ def __init__(self): |
314 | 314 | else: |
315 | 315 | self.fail("No exception raised") |
316 | 316 |
|
| 317 | + def test_single_exception_stacktrace(self): |
| 318 | + expected = '''Traceback (most recent call last): |
| 319 | + File "/opt/python-future/tests/test_future/test_utils.py", line 328, in test_single_exception_stacktrace |
| 320 | + raise CustomException('ERROR') |
| 321 | +''' |
| 322 | + if PY2: |
| 323 | + expected += 'CustomException: ERROR\n' |
| 324 | + else: |
| 325 | + expected += 'tests.test_future.test_utils.CustomException: ERROR\n' |
| 326 | + |
| 327 | + try: |
| 328 | + raise CustomException('ERROR') |
| 329 | + except: |
| 330 | + self.assertEqual(expected, traceback.format_exc()) |
| 331 | + else: |
| 332 | + self.fail('No exception raised') |
| 333 | + |
| 334 | + if PY2: |
| 335 | + def test_chained_exceptions_stacktrace(self): |
| 336 | + expected = '''Traceback (most recent call last): |
| 337 | + File "/opt/python-future/tests/test_future/test_utils.py", line 354, in test_chained_exceptions_stacktrace |
| 338 | + raise_from(CustomException('ERROR'), val_err) |
| 339 | + File "/opt/python-future/src/future/utils/__init__.py", line 456, in raise_from |
| 340 | + raise e |
| 341 | +CustomException: ERROR |
| 342 | +
|
| 343 | +The above exception was the direct cause of the following exception: |
| 344 | +
|
| 345 | + File "/opt/python-future/tests/test_future/test_utils.py", line 352, in test_chained_exceptions_stacktrace |
| 346 | + raise ValueError('Wooops') |
| 347 | +ValueError: Wooops |
| 348 | +''' |
| 349 | + |
| 350 | + try: |
| 351 | + try: |
| 352 | + raise ValueError('Wooops') |
| 353 | + except ValueError as val_err: |
| 354 | + raise_from(CustomException('ERROR'), val_err) |
| 355 | + except Exception as err: |
| 356 | + self.assertEqual(expected.splitlines(), traceback.format_exc().splitlines()) |
| 357 | + else: |
| 358 | + self.fail('No exception raised') |
| 359 | + |
| 360 | + |
| 361 | +class CustomException(Exception): |
| 362 | + if PY2: |
| 363 | + def __str__(self): |
| 364 | + out = Exception.__str__(self) |
| 365 | + if hasattr(self, '__cause__') and self.__cause__ and hasattr(self.__cause__, '__traceback__') and self.__cause__.__traceback__: |
| 366 | + out += '\n\nThe above exception was the direct cause of the following exception:\n\n' |
| 367 | + out += ''.join(traceback.format_tb(self.__cause__.__traceback__) + ['{}: {}'.format(self.__cause__.__class__.__name__, self.__cause__)]) |
| 368 | + return out |
| 369 | + else: |
| 370 | + pass |
| 371 | + |
317 | 372 |
|
318 | 373 | if __name__ == '__main__': |
319 | 374 | unittest.main() |
0 commit comments