|
1 | 1 | import doctest |
2 | 2 | import textwrap |
| 3 | +import traceback |
3 | 4 | import types |
4 | 5 | import unittest |
5 | 6 |
|
| 7 | +from test.support import BrokenIter |
| 8 | + |
6 | 9 |
|
7 | 10 | doctests = """ |
8 | 11 | ########### Tests borrowed from or inspired by test_genexps.py ############ |
@@ -706,6 +709,35 @@ def test_multiple_comprehension_name_reuse(self): |
706 | 709 | self._check_in_scopes(code, {"x": 2, "y": [3]}, ns={"x": 3}, scopes=["class"]) |
707 | 710 | self._check_in_scopes(code, {"x": 2, "y": [2]}, ns={"x": 3}, scopes=["function", "module"]) |
708 | 711 |
|
| 712 | + def test_exception_locations(self): |
| 713 | + # The location of an exception raised from __init__ or |
| 714 | + # __next__ should should be the iterator expression |
| 715 | + |
| 716 | + def init_raises(): |
| 717 | + try: |
| 718 | + [x for x in BrokenIter(init_raises=True)] |
| 719 | + except Exception as e: |
| 720 | + return e |
| 721 | + |
| 722 | + def next_raises(): |
| 723 | + try: |
| 724 | + [x for x in BrokenIter(next_raises=True)] |
| 725 | + except Exception as e: |
| 726 | + return e |
| 727 | + |
| 728 | + for func, expected in [(init_raises, "BrokenIter(init_raises=True)"), |
| 729 | + (next_raises, "BrokenIter(next_raises=True)"), |
| 730 | + ]: |
| 731 | + with self.subTest(func): |
| 732 | + exc = func() |
| 733 | + f = traceback.extract_tb(exc.__traceback__)[0] |
| 734 | + indent = 16 |
| 735 | + co = func.__code__ |
| 736 | + self.assertEqual(f.lineno, co.co_firstlineno + 2) |
| 737 | + self.assertEqual(f.end_lineno, co.co_firstlineno + 2) |
| 738 | + self.assertEqual(f.line[f.colno - indent : f.end_colno - indent], |
| 739 | + expected) |
| 740 | + |
709 | 741 | __test__ = {'doctests' : doctests} |
710 | 742 |
|
711 | 743 | def load_tests(loader, tests, pattern): |
|
0 commit comments