|
10 | 10 | import functools
|
11 | 11 | import contextlib
|
12 | 12 | import builtins
|
| 13 | +import traceback |
13 | 14 |
|
14 | 15 | # Test result of triple loop (too big to inline)
|
15 | 16 | TRIPLETS = [(0, 0, 0), (0, 0, 1), (0, 0, 2),
|
@@ -1143,6 +1144,51 @@ def test_error_iter(self):
|
1143 | 1144 | self.assertRaises(TypeError, iter, typ())
|
1144 | 1145 | self.assertRaises(ZeroDivisionError, iter, BadIterableClass())
|
1145 | 1146 |
|
| 1147 | + def test_exception_locations(self): |
| 1148 | + # The location of an exception raised from __init__ or |
| 1149 | + # __next__ should should be the iterator expression |
| 1150 | + |
| 1151 | + class Iter: |
| 1152 | + def __init__(self, init_raises=False, next_raises=False): |
| 1153 | + if init_raises: |
| 1154 | + 1/0 |
| 1155 | + self.next_raises = next_raises |
| 1156 | + |
| 1157 | + def __next__(self): |
| 1158 | + if self.next_raises: |
| 1159 | + 1/0 |
| 1160 | + |
| 1161 | + def __iter__(self): |
| 1162 | + return self |
| 1163 | + |
| 1164 | + def init_raises(): |
| 1165 | + try: |
| 1166 | + for x in Iter(init_raises=True): |
| 1167 | + pass |
| 1168 | + except Exception as e: |
| 1169 | + return e |
| 1170 | + |
| 1171 | + def next_raises(): |
| 1172 | + try: |
| 1173 | + for x in Iter(next_raises=True): |
| 1174 | + pass |
| 1175 | + except Exception as e: |
| 1176 | + return e |
| 1177 | + |
| 1178 | + for func, expected in [(init_raises, "Iter(init_raises=True)"), |
| 1179 | + (next_raises, "Iter(next_raises=True)"), |
| 1180 | + ]: |
| 1181 | + with self.subTest(func): |
| 1182 | + exc = func() |
| 1183 | + f = traceback.extract_tb(exc.__traceback__)[0] |
| 1184 | + indent = 16 |
| 1185 | + co = func.__code__ |
| 1186 | + self.assertEqual(f.lineno, co.co_firstlineno + 2) |
| 1187 | + self.assertEqual(f.end_lineno, co.co_firstlineno + 2) |
| 1188 | + self.assertEqual(f.line[f.colno - indent : f.end_colno - indent], |
| 1189 | + expected) |
| 1190 | + |
| 1191 | + |
1146 | 1192 |
|
1147 | 1193 | if __name__ == "__main__":
|
1148 | 1194 | unittest.main()
|
0 commit comments