Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
pybind11
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
open
pybind11
Commits
e26bd404
Commit
e26bd404
authored
Jan 14, 2021
by
Ralf W. Grosse-Kunstleve
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Calling deregister_instance after disowning via unique_ptr.
parent
4f135ce8
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
46 additions
and
21 deletions
+46
-21
tests/test_classh_wip.cpp
+35
-20
tests/test_classh_wip.py
+11
-1
No files found.
tests/test_classh_wip.cpp
View file @
e26bd404
...
@@ -54,17 +54,35 @@ using namespace pybind11_tests::classh_wip;
...
@@ -54,17 +54,35 @@ using namespace pybind11_tests::classh_wip;
template
<
typename
T
>
template
<
typename
T
>
struct
smart_holder_type_caster_load
{
struct
smart_holder_type_caster_load
{
using
holder_type
=
pybindit
::
memory
::
smart_holder
;
bool
load
(
handle
src
,
bool
/*convert*/
)
{
bool
load
(
handle
src
,
bool
/*convert*/
)
{
if
(
!
isinstance
<
T
>
(
src
))
if
(
!
isinstance
<
T
>
(
src
))
return
false
;
return
false
;
auto
inst
=
reinterpret_cast
<
instance
*>
(
src
.
ptr
());
auto
inst
=
reinterpret_cast
<
instance
*>
(
src
.
ptr
());
auto
v_h
=
inst
->
get_value_and_holder
(
get_type_info
(
typeid
(
T
)));
loaded_v_h
=
inst
->
get_value_and_holder
(
get_type_info
(
typeid
(
T
)));
smhldr_ptr
=
&
v_h
.
holder
<
pybindit
::
memory
::
smart_holder
>
();
if
(
!
loaded_v_h
.
holder_constructed
())
{
// IMPROVEABLE: Error message.
throw
std
::
runtime_error
(
"Missing value for wrapped C++ type:"
" Python instance is uninitialized or was disowned."
);
}
loaded_smhldr_ptr
=
&
loaded_v_h
.
holder
<
holder_type
>
();
return
true
;
return
true
;
}
}
std
::
unique_ptr
<
T
>
loaded_as_unique_ptr
()
{
void
*
value_void_ptr
=
loaded_v_h
.
value_ptr
();
auto
unq_ptr
=
loaded_smhldr_ptr
->
as_unique_ptr
<
mpty
>
();
loaded_v_h
.
holder
<
holder_type
>
().
~
holder_type
();
loaded_v_h
.
set_holder_constructed
(
false
);
loaded_v_h
.
value_ptr
()
=
nullptr
;
deregister_instance
(
loaded_v_h
.
inst
,
value_void_ptr
,
loaded_v_h
.
type
);
return
unq_ptr
;
}
protected
:
protected
:
pybindit
::
memory
::
smart_holder
*
smhldr_ptr
=
nullptr
;
value_and_holder
loaded_v_h
;
holder_type
*
loaded_smhldr_ptr
=
nullptr
;
};
};
template
<>
template
<>
...
@@ -127,12 +145,12 @@ struct type_caster<mpty> : smart_holder_type_caster_load<mpty> {
...
@@ -127,12 +145,12 @@ struct type_caster<mpty> : smart_holder_type_caster_load<mpty> {
// clang-format off
// clang-format off
operator
mpty
()
{
return
smhldr_ptr
->
lvalue_ref
<
mpty
>
();
}
operator
mpty
()
{
return
loaded_
smhldr_ptr
->
lvalue_ref
<
mpty
>
();
}
operator
mpty
&&
()
&&
{
return
smhldr_ptr
->
rvalue_ref
<
mpty
>
();
}
operator
mpty
&&
()
&&
{
return
loaded_
smhldr_ptr
->
rvalue_ref
<
mpty
>
();
}
operator
mpty
const
&
()
{
return
smhldr_ptr
->
lvalue_ref
<
mpty
>
();
}
operator
mpty
const
&
()
{
return
loaded_
smhldr_ptr
->
lvalue_ref
<
mpty
>
();
}
operator
mpty
&
()
{
return
smhldr_ptr
->
lvalue_ref
<
mpty
>
();
}
operator
mpty
&
()
{
return
loaded_
smhldr_ptr
->
lvalue_ref
<
mpty
>
();
}
operator
mpty
const
*
()
{
return
smhldr_ptr
->
as_raw_ptr_unowned
<
mpty
>
();
}
operator
mpty
const
*
()
{
return
loaded_
smhldr_ptr
->
as_raw_ptr_unowned
<
mpty
>
();
}
operator
mpty
*
()
{
return
smhldr_ptr
->
as_raw_ptr_unowned
<
mpty
>
();
}
operator
mpty
*
()
{
return
loaded_
smhldr_ptr
->
as_raw_ptr_unowned
<
mpty
>
();
}
// clang-format on
// clang-format on
...
@@ -331,7 +349,7 @@ struct type_caster<std::shared_ptr<mpty>> : smart_holder_type_caster_load<mpty>
...
@@ -331,7 +349,7 @@ struct type_caster<std::shared_ptr<mpty>> : smart_holder_type_caster_load<mpty>
template
<
typename
>
template
<
typename
>
using
cast_op_type
=
std
::
shared_ptr
<
mpty
>
;
using
cast_op_type
=
std
::
shared_ptr
<
mpty
>
;
operator
std
::
shared_ptr
<
mpty
>
()
{
return
smhldr_ptr
->
as_shared_ptr
<
mpty
>
();
}
operator
std
::
shared_ptr
<
mpty
>
()
{
return
loaded_
smhldr_ptr
->
as_shared_ptr
<
mpty
>
();
}
};
};
template
<>
template
<>
...
@@ -349,7 +367,7 @@ struct type_caster<std::shared_ptr<mpty const>> : smart_holder_type_caster_load<
...
@@ -349,7 +367,7 @@ struct type_caster<std::shared_ptr<mpty const>> : smart_holder_type_caster_load<
template
<
typename
>
template
<
typename
>
using
cast_op_type
=
std
::
shared_ptr
<
mpty
const
>
;
using
cast_op_type
=
std
::
shared_ptr
<
mpty
const
>
;
operator
std
::
shared_ptr
<
mpty
const
>
()
{
return
smhldr_ptr
->
as_shared_ptr
<
mpty
>
();
}
operator
std
::
shared_ptr
<
mpty
const
>
()
{
return
loaded_
smhldr_ptr
->
as_shared_ptr
<
mpty
>
();
}
};
};
template
<>
template
<>
...
@@ -398,10 +416,7 @@ struct type_caster<std::unique_ptr<mpty>> : smart_holder_type_caster_load<mpty>
...
@@ -398,10 +416,7 @@ struct type_caster<std::unique_ptr<mpty>> : smart_holder_type_caster_load<mpty>
template
<
typename
>
template
<
typename
>
using
cast_op_type
=
std
::
unique_ptr
<
mpty
>
;
using
cast_op_type
=
std
::
unique_ptr
<
mpty
>
;
operator
std
::
unique_ptr
<
mpty
>
()
{
operator
std
::
unique_ptr
<
mpty
>
()
{
return
loaded_as_unique_ptr
();
}
// MISSING: value_and_holder value_ptr reset, deregister_instance.
return
smhldr_ptr
->
as_unique_ptr
<
mpty
>
();
}
};
};
template
<>
template
<>
...
@@ -419,10 +434,7 @@ struct type_caster<std::unique_ptr<mpty const>> : smart_holder_type_caster_load<
...
@@ -419,10 +434,7 @@ struct type_caster<std::unique_ptr<mpty const>> : smart_holder_type_caster_load<
template
<
typename
>
template
<
typename
>
using
cast_op_type
=
std
::
unique_ptr
<
mpty
const
>
;
using
cast_op_type
=
std
::
unique_ptr
<
mpty
const
>
;
operator
std
::
unique_ptr
<
mpty
const
>
()
{
operator
std
::
unique_ptr
<
mpty
const
>
()
{
return
loaded_as_unique_ptr
();
}
// MISSING: value_and_holder value_ptr reset, deregister_instance.
return
smhldr_ptr
->
as_unique_ptr
<
mpty
>
();
}
};
};
}
// namespace detail
}
// namespace detail
...
@@ -466,7 +478,10 @@ TEST_SUBMODULE(classh_wip, m) {
...
@@ -466,7 +478,10 @@ TEST_SUBMODULE(classh_wip, m) {
m
.
def
(
"pass_mpty_uqmp"
,
pass_mpty_uqmp
);
m
.
def
(
"pass_mpty_uqmp"
,
pass_mpty_uqmp
);
m
.
def
(
"pass_mpty_uqcp"
,
pass_mpty_uqcp
);
m
.
def
(
"pass_mpty_uqcp"
,
pass_mpty_uqcp
);
m
.
def
(
"get_mtxt"
,
get_mtxt
);
// Requires pass_mpty_cref to work properly.
// Helpers, these require selected functions above to work, as indicated:
m
.
def
(
"get_mtxt"
,
get_mtxt
);
// pass_mpty_cref
m
.
def
(
"unique_ptr_roundtrip"
,
[](
std
::
unique_ptr
<
mpty
>
obj
)
{
return
obj
;
});
// pass_mpty_uqmp, rtrn_mpty_uqmp
}
}
}
// namespace classh_wip
}
// namespace classh_wip
...
...
tests/test_classh_wip.py
View file @
e26bd404
...
@@ -63,4 +63,14 @@ def test_pass_unique_ptr_disowns(pass_mpty, argm, rtrn):
...
@@ -63,4 +63,14 @@ def test_pass_unique_ptr_disowns(pass_mpty, argm, rtrn):
assert
pass_mpty
(
obj
)
==
rtrn
assert
pass_mpty
(
obj
)
==
rtrn
with
pytest
.
raises
(
RuntimeError
)
as
exc_info
:
with
pytest
.
raises
(
RuntimeError
)
as
exc_info
:
m
.
pass_mpty_uqmp
(
obj
)
m
.
pass_mpty_uqmp
(
obj
)
assert
str
(
exc_info
.
value
)
==
"Cannot disown nullptr (as_unique_ptr)."
assert
str
(
exc_info
.
value
)
==
(
"Missing value for wrapped C++ type:"
" Python instance is uninitialized or was disowned."
)
def
test_unique_ptr_roundtrip
(
num_round_trips
=
1000
):
recycled
=
m
.
mpty
(
"passenger"
)
for
_
in
range
(
num_round_trips
):
recycled
=
m
.
unique_ptr_roundtrip
(
recycled
)
assert
m
.
get_mtxt
(
recycled
)
==
"passenger"
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