|
7 | 7 | import pickle |
8 | 8 | import weakref |
9 | 9 | import errno |
| 10 | +import abc |
10 | 11 |
|
11 | 12 | from test.support import (TESTFN, captured_stderr, check_impl_detail, |
12 | 13 | check_warnings, cpython_only, gc_collect, run_unittest, |
@@ -1337,6 +1338,53 @@ def test_copy_pickle(self): |
1337 | 1338 | self.assertEqual(exc.name, orig.name) |
1338 | 1339 | self.assertEqual(exc.path, orig.path) |
1339 | 1340 |
|
| 1341 | + def test_exception_registration(self): |
| 1342 | + # See issue12029 |
| 1343 | + class A(Exception, metaclass=abc.ABCMeta): |
| 1344 | + pass |
| 1345 | + class B(Exception): |
| 1346 | + pass |
| 1347 | + A.register(B) |
| 1348 | + try: |
| 1349 | + raise B |
| 1350 | + except A: |
| 1351 | + pass |
| 1352 | + except B: |
| 1353 | + self.fail("Caught B, should have caught A") |
| 1354 | + |
| 1355 | + def test_exception_subclasscheck(self): |
| 1356 | + # Test that a bad __subclasscheck__ does not cause failure |
| 1357 | + class RaisingMeta(type): |
| 1358 | + def __subclasscheck__(self, cls): |
| 1359 | + raise RuntimeError |
| 1360 | + class RaisingCatchingMeta(type): |
| 1361 | + def __subclasscheck__(self, cls): |
| 1362 | + try: |
| 1363 | + raise RuntimeError |
| 1364 | + except RuntimeError: |
| 1365 | + pass |
| 1366 | + def recursion(): |
| 1367 | + return recursion() |
| 1368 | + class RecursingMeta(type): |
| 1369 | + def __subclasscheck__(self, cls): |
| 1370 | + recursion() |
| 1371 | + reclimit = sys.getrecursionlimit() |
| 1372 | + try: |
| 1373 | + sys.setrecursionlimit(1000) |
| 1374 | + for metaclass in [RaisingMeta, RaisingCatchingMeta, RecursingMeta]: |
| 1375 | + BadException = metaclass('BadException', (Exception,), {}) |
| 1376 | + try: |
| 1377 | + raise ValueError |
| 1378 | + # this handler should cause an exception that is ignored |
| 1379 | + except BadException: |
| 1380 | + self.fail('caught a bad exception but shouldn\'t') |
| 1381 | + except ValueError: |
| 1382 | + pass |
| 1383 | + else: |
| 1384 | + self.fail('ValueError not raised') |
| 1385 | + finally: |
| 1386 | + sys.setrecursionlimit(reclimit) |
| 1387 | + |
1340 | 1388 |
|
1341 | 1389 | if __name__ == '__main__': |
1342 | 1390 | unittest.main() |
0 commit comments