mirror of
https://github.com/pybind/pybind11.git
synced 2026-03-14 20:27:47 +00:00
Feature/local exception translator (#2650)
* Create a module_internals struct Since we now have two things that are going to be module local, it felt correct to add a struct to manage them. * Add local exception translators These are added via the register_local_exception_translator function and are then applied before the global translators * Add unit tests to show the local exception translator works * Fix a bug in the unit test with the string value of KeyError * Fix a formatting issue * Rename registered_local_types_cpp() Rename it to get_registered_local_types_cpp() to disambiguate from the new member of module_internals * Add additional comments to new local exception code path * Add a register_local_exception function * Add additional unit tests for register_local_exception * Use get_local_internals like get_internals * Update documentation for new local exception feature * Add back a missing space * Clean-up some issues in the docs * Remove the code duplication when translating exceptions Separated out the exception processing into a standalone function in the details namespace. Clean-up some comments as per PR notes as well * Remove the code duplication in register_exception * Cleanup some formatting things caught by clang-format * Remove the templates from exception translators But I added a using declaration to alias the type. * Remove the extra local from local_internals variable names * Add an extra explanatory comment to local_internals * Fix a typo in the code
This commit is contained in:
@@ -25,7 +25,7 @@ def test_error_already_set(msg):
|
||||
assert msg(excinfo.value) == "foo"
|
||||
|
||||
|
||||
def test_cross_module_exceptions():
|
||||
def test_cross_module_exceptions(msg):
|
||||
with pytest.raises(RuntimeError) as excinfo:
|
||||
cm.raise_runtime_error()
|
||||
assert str(excinfo.value) == "My runtime error"
|
||||
@@ -45,6 +45,15 @@ def test_cross_module_exceptions():
|
||||
with pytest.raises(StopIteration) as excinfo:
|
||||
cm.throw_stop_iteration()
|
||||
|
||||
with pytest.raises(cm.LocalSimpleException) as excinfo:
|
||||
cm.throw_local_simple_error()
|
||||
assert msg(excinfo.value) == "external mod"
|
||||
|
||||
with pytest.raises(KeyError) as excinfo:
|
||||
cm.throw_local_error()
|
||||
# KeyError is a repr of the key, so it has an extra set of quotes
|
||||
assert str(excinfo.value) == "'just local'"
|
||||
|
||||
|
||||
# TODO: FIXME
|
||||
@pytest.mark.xfail(
|
||||
@@ -221,3 +230,21 @@ def test_invalid_repr():
|
||||
|
||||
with pytest.raises(TypeError):
|
||||
m.simple_bool_passthrough(MyRepr())
|
||||
|
||||
|
||||
def test_local_translator(msg):
|
||||
"""Tests that a local translator works and that the local translator from
|
||||
the cross module is not applied"""
|
||||
with pytest.raises(RuntimeError) as excinfo:
|
||||
m.throws6()
|
||||
assert msg(excinfo.value) == "MyException6 only handled in this module"
|
||||
|
||||
with pytest.raises(RuntimeError) as excinfo:
|
||||
m.throws_local_error()
|
||||
assert not isinstance(excinfo.value, KeyError)
|
||||
assert msg(excinfo.value) == "never caught"
|
||||
|
||||
with pytest.raises(Exception) as excinfo:
|
||||
m.throws_local_simple_error()
|
||||
assert not isinstance(excinfo.value, cm.LocalSimpleException)
|
||||
assert msg(excinfo.value) == "this mod"
|
||||
|
||||
Reference in New Issue
Block a user