|
| 1 | +import pytest |
| 2 | + |
| 3 | +import env |
1 | 4 | from pybind11_tests import ConstructorStats |
2 | 5 | from pybind11_tests import modules as m |
3 | 6 | from pybind11_tests.modules import subsubmodule as ms |
@@ -89,3 +92,30 @@ def test_builtin_key_type(): |
89 | 92 | keys = __builtins__.__dict__.keys() |
90 | 93 |
|
91 | 94 | assert {type(k) for k in keys} == {str} |
| 95 | + |
| 96 | + |
| 97 | +@pytest.mark.xfail("env.PYPY", reason="PyModule_GetName()") |
| 98 | +def test_def_submodule_failures(): |
| 99 | + sm = m.def_submodule(m, b"ScratchSubModuleName") # Using bytes to show it works. |
| 100 | + assert sm.__name__ == m.__name__ + "." + "ScratchSubModuleName" |
| 101 | + malformed_utf8 = b"\x80" |
| 102 | + if env.PYPY: |
| 103 | + # It is not worth the effort finding a trigger for a failure when running with PyPy. |
| 104 | + pytest.skip("Sufficiently exercised on platforms other than PyPy.") |
| 105 | + else: |
| 106 | + # Meant to trigger PyModule_GetName() failure: |
| 107 | + sm_name_orig = sm.__name__ |
| 108 | + sm.__name__ = malformed_utf8 |
| 109 | + try: |
| 110 | + with pytest.raises(Exception): |
| 111 | + # Seen with Python 3.9: SystemError: nameless module |
| 112 | + # But we do not want to exercise the internals of PyModule_GetName(), which could |
| 113 | + # change in future versions of Python, but a bad __name__ is very likely to cause |
| 114 | + # some kind of failure indefinitely. |
| 115 | + m.def_submodule(sm, b"SubSubModuleName") |
| 116 | + finally: |
| 117 | + # Clean up to ensure nothing gets upset by a module with an invalid __name__. |
| 118 | + sm.__name__ = sm_name_orig # Purely precautionary. |
| 119 | + # Meant to trigger PyImport_AddModule() failure: |
| 120 | + with pytest.raises(UnicodeDecodeError): |
| 121 | + m.def_submodule(sm, malformed_utf8) |
0 commit comments