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
149be460
Commit
149be460
authored
Jan 23, 2021
by
Ralf W. Grosse-Kunstleve
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Converting test_unique_ptr_member to using classh: fully working, ASAN, MSAN, UBSAN clean.
parent
73cb257e
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
24 additions
and
94 deletions
+24
-94
tests/test_unique_ptr_member.cpp
+13
-74
tests/test_unique_ptr_member.py
+11
-20
No files found.
tests/test_unique_ptr_member.cpp
View file @
149be460
#include "pybind11_tests.h"
#include <pybind11/
vptr_holder
.h>
#include <pybind11/
classh
.h>
#include <iostream>
#include <memory>
namespace
pybind11_tests
{
namespace
unique_ptr_member
{
inline
void
to_cout
(
std
::
string
text
)
{
std
::
cout
<<
text
<<
std
::
endl
;
}
class
pointee
{
// NOT copyable.
public:
public:
pointee
()
=
default
;
int
get_int
()
const
{
to_cout
(
"pointee::get_int()"
);
//TRIGGER_SEGSEV
return
213
;
}
~
pointee
()
{
to_cout
(
"~pointee()"
);
}
int
get_int
()
const
{
return
213
;
}
private
:
private
:
pointee
(
const
pointee
&
)
=
delete
;
pointee
(
pointee
&&
)
=
delete
;
pointee
(
pointee
&&
)
=
delete
;
pointee
&
operator
=
(
const
pointee
&
)
=
delete
;
pointee
&
operator
=
(
pointee
&&
)
=
delete
;
};
...
...
@@ -34,88 +25,36 @@ inline std::unique_ptr<pointee> make_unique_pointee() {
}
class
ptr_owner
{
public
:
public
:
explicit
ptr_owner
(
std
::
unique_ptr
<
pointee
>
ptr
)
:
ptr_
(
std
::
move
(
ptr
))
{}
bool
is_owner
()
const
{
return
bool
(
ptr_
);
}
std
::
unique_ptr
<
pointee
>
give_up_ownership_via_unique_ptr
()
{
return
std
::
move
(
ptr_
);
}
std
::
shared_ptr
<
pointee
>
give_up_ownership_via_shared_ptr
()
{
return
std
::
move
(
ptr_
);
}
std
::
unique_ptr
<
pointee
>
give_up_ownership_via_unique_ptr
()
{
return
std
::
move
(
ptr_
);
}
std
::
shared_ptr
<
pointee
>
give_up_ownership_via_shared_ptr
()
{
return
std
::
move
(
ptr_
);
}
private
:
private
:
std
::
unique_ptr
<
pointee
>
ptr_
;
};
// Just to have a minimal example of a typical C++ pattern.
inline
int
cpp_pattern
()
{
auto
obj
=
make_unique_pointee
();
int
result
=
(
obj
?
1
:
8
);
obj
->
get_int
();
ptr_owner
owner
(
std
::
move
(
obj
));
result
=
result
*
10
+
(
obj
?
8
:
1
);
result
=
result
*
10
+
(
owner
.
is_owner
()
?
1
:
8
);
to_cout
(
"before give up"
);
auto
reclaimed
=
owner
.
give_up_ownership_via_shared_ptr
();
to_cout
(
"after give up"
);
result
=
result
*
10
+
(
owner
.
is_owner
()
?
8
:
1
);
result
=
result
*
10
+
(
reclaimed
?
1
:
8
);
reclaimed
.
reset
();
to_cout
(
"after del"
);
result
=
result
*
10
+
(
reclaimed
?
8
:
1
);
return
result
;
}
}
// namespace unique_ptr_member
}
// namespace pybind11_tests
namespace
pybind11
{
namespace
detail
{
template
<>
struct
type_caster
<
std
::
unique_ptr
<
pybind11_tests
::
unique_ptr_member
::
pointee
>>
{
public
:
PYBIND11_TYPE_CASTER
(
std
::
unique_ptr
<
pybind11_tests
::
unique_ptr_member
::
pointee
>
,
_
(
"std::unique_ptr<pybind11_tests::unique_ptr_member::pointee>"
));
bool
load
(
handle
/* src */
,
bool
)
{
throw
std
::
runtime_error
(
"Not implemented: load"
);
}
static
handle
cast
(
std
::
unique_ptr
<
pybind11_tests
::
unique_ptr_member
::
pointee
>
/* src */
,
return_value_policy
/* policy */
,
handle
/* parent */
)
{
throw
std
::
runtime_error
(
"Not implemented: cast"
);
}
};
}
// namespace detail
}
// namespace pybind11
PYBIND11_CLASSH_TYPE_CASTERS
(
pybind11_tests
::
unique_ptr_member
::
pointee
)
namespace
pybind11_tests
{
namespace
unique_ptr_member
{
TEST_SUBMODULE
(
unique_ptr_member
,
m
)
{
m
.
def
(
"to_cout"
,
to_cout
);
py
::
class_
<
pointee
,
py
::
vptr_holder
<
pointee
>>
(
m
,
"pointee"
)
.
def
(
py
::
init
<>
())
.
def
(
"get_int"
,
&
pointee
::
get_int
);
py
::
classh
<
pointee
>
(
m
,
"pointee"
).
def
(
py
::
init
<>
()).
def
(
"get_int"
,
&
pointee
::
get_int
);
m
.
def
(
"make_unique_pointee"
,
make_unique_pointee
);
py
::
class_
<
ptr_owner
>
(
m
,
"ptr_owner"
)
.
def
(
py
::
init
<
std
::
unique_ptr
<
pointee
>>
(),
py
::
arg
(
"ptr"
))
.
def
(
"is_owner"
,
&
ptr_owner
::
is_owner
)
.
def
(
"give_up_ownership_via_unique_ptr"
,
&
ptr_owner
::
give_up_ownership_via_unique_ptr
)
.
def
(
"give_up_ownership_via_shared_ptr"
,
&
ptr_owner
::
give_up_ownership_via_shared_ptr
);
m
.
def
(
"cpp_pattern"
,
cpp_pattern
);
.
def
(
"give_up_ownership_via_unique_ptr"
,
&
ptr_owner
::
give_up_ownership_via_unique_ptr
)
.
def
(
"give_up_ownership_via_shared_ptr"
,
&
ptr_owner
::
give_up_ownership_via_shared_ptr
);
}
}
// namespace unique_ptr_member
...
...
tests/test_unique_ptr_member.py
View file @
149be460
...
...
@@ -5,34 +5,25 @@ from pybind11_tests import unique_ptr_member as m
def
test_make_unique_pointee
():
m
.
to_cout
(
""
)
obj
=
m
.
make_unique_pointee
()
assert
obj
.
get_int
()
==
213
m
.
to_cout
(
""
)
def
test_pointee_and_ptr_owner
():
m
.
to_cout
(
""
)
@pytest.mark.parametrize
(
"give_up_ownership_via"
,
[
"give_up_ownership_via_unique_ptr"
,
"give_up_ownership_via_shared_ptr"
],
)
def
test_pointee_and_ptr_owner
(
give_up_ownership_via
):
obj
=
m
.
pointee
()
assert
obj
.
get_int
()
==
213
owner
=
m
.
ptr_owner
(
obj
)
with
pytest
.
raises
(
RuntimeError
)
as
exc_info
:
obj
.
get_int
()
assert
str
(
exc_info
.
value
)
==
"Invalid object instance"
assert
(
str
(
exc_info
.
value
)
==
"Missing value for wrapped C++ type: Python instance is uninitialized or was disowned."
)
assert
owner
.
is_owner
()
m
.
to_cout
(
"before give up"
)
reclaimed
=
owner
.
give_up_ownership_via_shared_ptr
()
m
.
to_cout
(
"after give up"
)
reclaimed
=
getattr
(
owner
,
give_up_ownership_via
)()
assert
not
owner
.
is_owner
()
# assert reclaimed.get_int() == 213
del
reclaimed
m
.
to_cout
(
"after del"
)
m
.
to_cout
(
"3"
)
m
.
to_cout
(
""
)
def
test_cpp_pattern
():
m
.
to_cout
(
""
)
res
=
m
.
cpp_pattern
()
assert
res
==
111111
m
.
to_cout
(
""
)
assert
reclaimed
.
get_int
()
==
213
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