|
43 | 43 | Py_GIL_DISABLED, |
44 | 44 | no_rerun, |
45 | 45 | force_not_colorized_test_class, |
| 46 | + catch_unraisable_exception |
46 | 47 | ) |
47 | 48 | from test.support.import_helper import ( |
48 | 49 | forget, make_legacy_pyc, unlink, unload, ready_to_import, |
@@ -2540,6 +2541,32 @@ def test_disallowed_reimport(self): |
2540 | 2541 | excsnap = _interpreters.run_string(interpid, script) |
2541 | 2542 | self.assertIsNot(excsnap, None) |
2542 | 2543 |
|
| 2544 | + @requires_subinterpreters |
| 2545 | + def test_pyinit_function_raises_exception(self): |
| 2546 | + # gh-144601: PyInit functions that raised exceptions would cause a |
| 2547 | + # crash when imported from a subinterpreter. |
| 2548 | + import _testsinglephase |
| 2549 | + filename = _testsinglephase.__file__ |
| 2550 | + script = f"""if True: |
| 2551 | + from test.test_import import import_extension_from_file |
| 2552 | +
|
| 2553 | + import_extension_from_file('_testsinglephase_raise_exception', {filename!r})""" |
| 2554 | + |
| 2555 | + interp = _interpreters.create() |
| 2556 | + try: |
| 2557 | + with catch_unraisable_exception() as cm: |
| 2558 | + exception = _interpreters.run_string(interp, script) |
| 2559 | + unraisable = cm.unraisable |
| 2560 | + finally: |
| 2561 | + _interpreters.destroy(interp) |
| 2562 | + |
| 2563 | + self.assertIsNotNone(exception) |
| 2564 | + self.assertIsNotNone(exception.type.__name__, "ImportError") |
| 2565 | + self.assertIsNotNone(exception.msg, "failed to import from subinterpreter due to exception") |
| 2566 | + self.assertIsNotNone(unraisable) |
| 2567 | + self.assertIs(unraisable.exc_type, RuntimeError) |
| 2568 | + self.assertEqual(str(unraisable.exc_value), "evil") |
| 2569 | + |
2543 | 2570 |
|
2544 | 2571 | class TestSinglePhaseSnapshot(ModuleSnapshot): |
2545 | 2572 | """A representation of a single-phase init module for testing. |
|
0 commit comments