Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
gaoqiong
pybind11
Commits
4d90f1a1
Unverified
Commit
4d90f1a1
authored
Jul 31, 2020
by
jbarlow83
Committed by
GitHub
Jul 31, 2020
Browse files
Add error_scope to py::class_::dealloc() to protect destructor calls (#2342)
Fixes issue #1878
parent
b8047245
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
24 additions
and
0 deletions
+24
-0
include/pybind11/pybind11.h
include/pybind11/pybind11.h
+7
-0
tests/test_class.cpp
tests/test_class.cpp
+11
-0
tests/test_class.py
tests/test_class.py
+6
-0
No files found.
include/pybind11/pybind11.h
View file @
4d90f1a1
...
...
@@ -1388,6 +1388,13 @@ private:
/// Deallocates an instance; via holder, if constructed; otherwise via operator delete.
static
void
dealloc
(
detail
::
value_and_holder
&
v_h
)
{
// We could be deallocating because we are cleaning up after a Python exception.
// If so, the Python error indicator will be set. We need to clear that before
// running the destructor, in case the destructor code calls more Python.
// If we don't, the Python API will exit with an exception, and pybind11 will
// throw error_already_set from the C++ destructor which is forbidden and triggers
// std::terminate().
error_scope
scope
;
if
(
v_h
.
holder_constructed
())
{
v_h
.
holder
<
holder_type
>
().
~
holder_type
();
v_h
.
set_holder_constructed
(
false
);
...
...
tests/test_class.cpp
View file @
4d90f1a1
...
...
@@ -379,6 +379,17 @@ TEST_SUBMODULE(class_, m) {
// test_non_final_final
struct
IsNonFinalFinal
{};
py
::
class_
<
IsNonFinalFinal
>
(
m
,
"IsNonFinalFinal"
,
py
::
is_final
());
struct
PyPrintDestructor
{
PyPrintDestructor
()
{}
~
PyPrintDestructor
()
{
py
::
print
(
"Print from destructor"
);
}
void
throw_something
()
{
throw
std
::
runtime_error
(
"error"
);
}
};
py
::
class_
<
PyPrintDestructor
>
(
m
,
"PyPrintDestructor"
)
.
def
(
py
::
init
<>
())
.
def
(
"throw_something"
,
&
PyPrintDestructor
::
throw_something
);
}
template
<
int
N
>
class
BreaksBase
{
public
:
...
...
tests/test_class.py
View file @
4d90f1a1
...
...
@@ -323,3 +323,9 @@ def test_non_final_final():
class
PyNonFinalFinalChild
(
m
.
IsNonFinalFinal
):
pass
assert
str
(
exc_info
.
value
).
endswith
(
"is not an acceptable base type"
)
# https://github.com/pybind/pybind11/issues/1878
def
test_exception_rvalue_abort
():
with
pytest
.
raises
(
RuntimeError
):
m
.
PyPrintDestructor
().
throw_something
()
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment