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
031a700d
Unverified
Commit
031a700d
authored
Aug 26, 2021
by
Jouke Witteveen
Committed by
GitHub
Aug 26, 2021
Browse files
Add make_simple_namespace function and tests (#2840)
Co-authored-by:
Jouke Witteveen
<
j.witteveen@cosine.nl
>
parent
c8ce4b8d
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
78 additions
and
1 deletion
+78
-1
docs/advanced/pycpp/object.rst
docs/advanced/pycpp/object.rst
+42
-1
include/pybind11/cast.h
include/pybind11/cast.h
+10
-0
tests/test_pytypes.cpp
tests/test_pytypes.cpp
+13
-0
tests/test_pytypes.py
tests/test_pytypes.py
+13
-0
No files found.
docs/advanced/pycpp/object.rst
View file @
031a700d
...
...
@@ -20,6 +20,47 @@ Available types include :class:`handle`, :class:`object`, :class:`bool_`,
Be sure to review the :ref:`pytypes_gotchas` before using this heavily in
your C++ API.
.. _instantiating_compound_types:
Instantiating compound Python types from C++
============================================
Dictionaries can be initialized in the :class:`dict` constructor:
.. code-block:: cpp
using namespace pybind11::literals; // to bring in the `_a` literal
py::dict d("spam"_a=py::none(), "eggs"_a=42);
A tuple of python objects can be instantiated using :func:`py::make_tuple`:
.. code-block:: cpp
py::tuple tup = py::make_tuple(42, py::none(), "spam");
Each element is converted to a supported Python type.
A `simple namespace`_ can be instantiated using
:func:`py::make_simple_namespace`:
.. code-block:: cpp
using namespace pybind11::literals; // to bring in the `_a` literal
py::object ns = py::make_simple_namespace("spam"_a=py::none(), "eggs"_a=42);
Attributes on a namespace can be modified with the :func:`py::delattr`,
:func:`py::getattr`, and :func:`py::setattr` functions. Simple namespaces can
be useful as lightweight stand-ins for class instances.
.. note::
``make_simple_namespace`` is not available in Python 2.
.. versionchanged:: 2.8
``make_simple_namespace`` added.
.. _simple namespace: https://docs.python.org/3/library/types.html#types.SimpleNamespace
.. _casting_back_and_forth:
Casting back and forth
...
...
@@ -30,7 +71,7 @@ types to Python, which can be done using :func:`py::cast`:
.. code-block:: cpp
MyClass *cls = ..;
MyClass *cls = ..
.
;
py::object obj = py::cast(cls);
The reverse direction uses the following syntax:
...
...
include/pybind11/cast.h
View file @
031a700d
...
...
@@ -1018,6 +1018,16 @@ template <return_value_policy policy = return_value_policy::automatic_reference,
return
result
;
}
#if PY_VERSION_HEX >= 0x03030000
template
<
typename
...
Args
,
typename
=
detail
::
enable_if_t
<
args_are_all_keyword_or_ds
<
Args
...>()
>>
object
make_simple_namespace
(
Args
&&
...
args_
)
{
PyObject
*
ns
=
_PyNamespace_New
(
dict
(
std
::
forward
<
Args
>
(
args_
)...).
ptr
());
if
(
!
ns
)
throw
error_already_set
();
return
reinterpret_steal
<
object
>
(
ns
);
}
#endif
/// \ingroup annotations
/// Annotation for arguments
struct
arg
{
...
...
tests/test_pytypes.cpp
View file @
031a700d
...
...
@@ -70,6 +70,19 @@ TEST_SUBMODULE(pytypes, m) {
m
.
def
(
"dict_contains"
,
[](
const
py
::
dict
&
dict
,
const
char
*
val
)
{
return
dict
.
contains
(
val
);
});
// test_tuple
m
.
def
(
"get_tuple"
,
[]()
{
return
py
::
make_tuple
(
42
,
py
::
none
(),
"spam"
);
});
#if PY_VERSION_HEX >= 0x03030000
// test_simple_namespace
m
.
def
(
"get_simple_namespace"
,
[]()
{
auto
ns
=
py
::
make_simple_namespace
(
"attr"
_a
=
42
,
"x"
_a
=
"foo"
,
"wrong"
_a
=
1
);
py
::
delattr
(
ns
,
"wrong"
);
py
::
setattr
(
ns
,
"right"
,
py
::
int_
(
2
));
return
ns
;
});
#endif
// test_str
m
.
def
(
"str_from_string"
,
[]()
{
return
py
::
str
(
std
::
string
(
"baz"
));
});
m
.
def
(
"str_from_bytes"
,
[]()
{
return
py
::
str
(
py
::
bytes
(
"boo"
,
3
));
});
...
...
tests/test_pytypes.py
View file @
031a700d
...
...
@@ -99,6 +99,19 @@ def test_dict(capture, doc):
assert
m
.
dict_keyword_constructor
()
==
{
"x"
:
1
,
"y"
:
2
,
"z"
:
3
}
def
test_tuple
():
assert
m
.
get_tuple
()
==
(
42
,
None
,
"spam"
)
@
pytest
.
mark
.
skipif
(
"env.PY2"
)
def
test_simple_namespace
():
ns
=
m
.
get_simple_namespace
()
assert
ns
.
attr
==
42
assert
ns
.
x
==
"foo"
assert
ns
.
right
==
2
assert
not
hasattr
(
ns
,
"wrong"
)
def
test_str
(
doc
):
assert
m
.
str_from_string
().
encode
().
decode
()
==
"baz"
assert
m
.
str_from_bytes
().
encode
().
decode
()
==
"boo"
...
...
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