|
42 | 42 | requires_gil_enabled, |
43 | 43 | Py_GIL_DISABLED, |
44 | 44 | force_not_colorized_test_class, |
| 45 | + catch_unraisable_exception |
45 | 46 | ) |
46 | 47 | from test.support.import_helper import ( |
47 | 48 | forget, make_legacy_pyc, unlink, unload, ready_to_import, |
@@ -2559,6 +2560,32 @@ def test_disallowed_reimport(self): |
2559 | 2560 | excsnap = _interpreters.run_string(interpid, script) |
2560 | 2561 | self.assertIsNot(excsnap, None) |
2561 | 2562 |
|
| 2563 | + @requires_subinterpreters |
| 2564 | + def test_pyinit_function_raises_exception(self): |
| 2565 | + # gh-144601: PyInit functions that raised exceptions would cause a |
| 2566 | + # crash when imported from a subinterpreter. |
| 2567 | + import _testsinglephase |
| 2568 | + filename = _testsinglephase.__file__ |
| 2569 | + script = f"""if True: |
| 2570 | + from test.test_import import import_extension_from_file |
| 2571 | +
|
| 2572 | + import_extension_from_file('_testsinglephase_raise_exception', {filename!r})""" |
| 2573 | + |
| 2574 | + interp = _interpreters.create() |
| 2575 | + try: |
| 2576 | + with catch_unraisable_exception() as cm: |
| 2577 | + exception = _interpreters.run_string(interp, script) |
| 2578 | + unraisable = cm.unraisable |
| 2579 | + finally: |
| 2580 | + _interpreters.destroy(interp) |
| 2581 | + |
| 2582 | + self.assertIsNotNone(exception) |
| 2583 | + self.assertIsNotNone(exception.type.__name__, "ImportError") |
| 2584 | + self.assertIsNotNone(exception.msg, "failed to import from subinterpreter due to exception") |
| 2585 | + self.assertIsNotNone(unraisable) |
| 2586 | + self.assertIs(unraisable.exc_type, RuntimeError) |
| 2587 | + self.assertEqual(str(unraisable.exc_value), "evil") |
| 2588 | + |
2562 | 2589 |
|
2563 | 2590 | class TestSinglePhaseSnapshot(ModuleSnapshot): |
2564 | 2591 | """A representation of a single-phase init module for testing. |
|
0 commit comments