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
44fa79ca
Unverified
Commit
44fa79ca
authored
Sep 04, 2020
by
Eric Cousineau
Committed by
GitHub
Sep 04, 2020
Browse files
pytypes: Add Gotchas section about default-constructed wrapper types and py::none() (#2362)
parent
72b06b86
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
45 additions
and
0 deletions
+45
-0
docs/advanced/pycpp/object.rst
docs/advanced/pycpp/object.rst
+27
-0
tests/test_pytypes.cpp
tests/test_pytypes.cpp
+10
-0
tests/test_pytypes.py
tests/test_pytypes.py
+8
-0
No files found.
docs/advanced/pycpp/object.rst
View file @
44fa79ca
...
...
@@ -15,6 +15,11 @@ Available types include :class:`handle`, :class:`object`, :class:`bool_`,
:class:`iterable`, :class:`iterator`, :class:`function`, :class:`buffer`,
:class:`array`, and :class:`array_t`.
.. warning::
Be sure to review the :ref:`pytypes_gotchas` before using this heavily in
your C++ API.
Casting back and forth
======================
...
...
@@ -178,3 +183,25 @@ Python exceptions from wrapper classes will be thrown as a ``py::error_already_s
See :ref:`Handling exceptions from Python in C++
<handling_python_exceptions_cpp>` for more information on handling exceptions
raised when calling C++ wrapper classes.
.. _pytypes_gotchas:
Gotchas
=======
Default-Constructed Wrappers
----------------------------
When a wrapper type is default-constructed, it is **not** a valid Python object (i.e. it is not ``py::none()``). It is simply the same as
``PyObject*`` null pointer. To check for this, use
``static_cast<bool>(my_wrapper)``.
Assigning py::none() to wrappers
--------------------------------
You may be tempted to use types like ``py::str`` and ``py::dict`` in C++
signatures (either pure C++, or in bound signatures), and assign them default
values of ``py::none()``. However, in a best case scenario, it will fail fast
because ``None`` is not convertible to that type (e.g. ``py::dict``), or in a
worse case scenario, it will silently work but corrupt the types you want to
work with (e.g. ``py::str(py::none())`` will yield ``"None"`` in Python).
tests/test_pytypes.cpp
View file @
44fa79ca
...
...
@@ -324,6 +324,16 @@ TEST_SUBMODULE(pytypes, m) {
return
a
[
py
::
slice
(
0
,
-
1
,
2
)];
});
// See #2361
m
.
def
(
"issue2361_str_implicit_copy_none"
,
[]()
{
py
::
str
is_this_none
=
py
::
none
();
return
is_this_none
;
});
m
.
def
(
"issue2361_dict_implicit_copy_none"
,
[]()
{
py
::
dict
is_this_none
=
py
::
none
();
return
is_this_none
;
});
m
.
def
(
"test_memoryview_object"
,
[](
py
::
buffer
b
)
{
return
py
::
memoryview
(
b
);
});
...
...
tests/test_pytypes.py
View file @
44fa79ca
...
...
@@ -326,6 +326,14 @@ def test_list_slicing():
assert
li
[::
2
]
==
m
.
test_list_slicing
(
li
)
def
test_issue2361
():
# See issue #2361
assert
m
.
issue2361_str_implicit_copy_none
()
==
"None"
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
assert
m
.
issue2361_dict_implicit_copy_none
()
assert
"'NoneType' object is not iterable"
in
str
(
excinfo
.
value
)
@
pytest
.
mark
.
parametrize
(
'method, args, fmt, expected_view'
,
[
(
m
.
test_memoryview_object
,
(
b
'red'
,),
'B'
,
b
'red'
),
(
m
.
test_memoryview_buffer_info
,
(
b
'green'
,),
'B'
,
b
'green'
),
...
...
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