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
031a700d
Unverified
Commit
031a700d
authored
Aug 26, 2021
by
Jouke Witteveen
Committed by
GitHub
Aug 26, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add make_simple_namespace function and tests (#2840)
Co-authored-by: Jouke Witteveen <j.witteveen@cosine.nl>
parent
c8ce4b8d
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
78 additions
and
1 deletions
+78
-1
docs/advanced/pycpp/object.rst
+42
-1
include/pybind11/cast.h
+10
-0
tests/test_pytypes.cpp
+13
-0
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