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
178c8a89
Commit
178c8a89
authored
May 10, 2016
by
Wenzel Jakob
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
nicer type_caster::load() calling conventions
parent
5984baaf
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
213 additions
and
71 deletions
+213
-71
docs/advanced.rst
+52
-2
docs/release.rst
+1
-1
example/example11.cpp
+19
-2
example/example11.py
+5
-1
example/example11.ref
+7
-0
include/pybind11/attr.h
+11
-2
include/pybind11/cast.h
+59
-17
include/pybind11/common.h
+1
-1
include/pybind11/complex.h
+2
-0
include/pybind11/eigen.h
+3
-0
include/pybind11/pybind11.h
+24
-16
include/pybind11/pytypes.h
+29
-29
No files found.
docs/advanced.rst
View file @
178c8a89
...
@@ -903,7 +903,7 @@ its popularity and widespread adoption, pybind11 provides transparent
...
@@ -903,7 +903,7 @@ its popularity and widespread adoption, pybind11 provides transparent
conversion support between Eigen and Scientific Python linear algebra data types.
conversion support between Eigen and Scientific Python linear algebra data types.
Specifically, when including the optional header file :file:`pybind11/eigen.h`,
Specifically, when including the optional header file :file:`pybind11/eigen.h`,
pybind11 will automatically and transparently convert
pybind11 will automatically and transparently convert
1. Static and dynamic Eigen dense vectors and matrices to instances of
1. Static and dynamic Eigen dense vectors and matrices to instances of
``numpy.ndarray`` (and vice versa).
``numpy.ndarray`` (and vice versa).
...
@@ -1250,11 +1250,31 @@ The reverse direction uses the following syntax:
...
@@ -1250,11 +1250,31 @@ The reverse direction uses the following syntax:
MyClass *cls = obj.cast<MyClass *>();
MyClass *cls = obj.cast<MyClass *>();
When conversion fails, both directions throw the exception :class:`cast_error`.
When conversion fails, both directions throw the exception :class:`cast_error`.
It is also possible to call python functions via ``operator()``.
.. code-block:: cpp
py::function f = <...>;
py::object result_py = f(1234, "hello", some_instance);
MyClass &result = result_py.cast<MyClass>();
The special ``f(*args)`` and ``f(*args, **kwargs)`` syntax is also supported to
supply arbitrary argument and keyword lists, although these cannot be mixed
with other parameters.
.. code-block:: cpp
py::function f = <...>;
py::tuple args = py::make_tuple(1234);
py::dict kwargs;
kwargs["y"] = py::cast(5678);
py::object result = f(*args, **kwargs);
.. seealso::
.. seealso::
The file :file:`example/example2.cpp` contains a complete example that
The file :file:`example/example2.cpp` contains a complete example that
demonstrates passing native Python types in more detail.
demonstrates passing native Python types in more detail. The file
:file:`example/example11.cpp` discusses usage of ``args`` and ``kwargs``.
Default arguments revisited
Default arguments revisited
===========================
===========================
...
@@ -1303,6 +1323,36 @@ like so:
...
@@ -1303,6 +1323,36 @@ like so:
py::class_<MyClass>("MyClass")
py::class_<MyClass>("MyClass")
.def("myFunction", py::arg("arg") = (SomeType *) nullptr);
.def("myFunction", py::arg("arg") = (SomeType *) nullptr);
Binding functions that accept arbitrary numbers of arguments and keywords arguments
===================================================================================
Python provides a useful mechanism to define functions that accept arbitrary
numbers of arguments and keyword arguments:
.. code-block:: cpp
def generic(*args, **kwargs):
# .. do something with args and kwargs
Such functions can also be created using pybind11:
.. code-block:: cpp
void generic(py::args args, py::kwargs kwargs) {
/// .. do something with args
if (kwargs)
/// .. do something with kwargs
}
/// Binding code
m.def("generic", &generic);
(See ``example/example11.cpp``). The class ``py::args`` derives from
``py::list`` and ``py::kwargs`` derives from ``py::dict`` Note that the
``kwargs`` argument is invalid if no keyword arguments were actually provided.
Please refer to the other examples for details on how to iterate over these,
and on how to cast their entries into C++ objects.
Partitioning code over multiple extension modules
Partitioning code over multiple extension modules
=================================================
=================================================
...
...
docs/release.rst
View file @
178c8a89
...
@@ -9,7 +9,7 @@ To release a new version of pybind11:
...
@@ -9,7 +9,7 @@ To release a new version of pybind11:
- ``git push --tags``.
- ``git push --tags``.
- ``python setup.py sdist upload``.
- ``python setup.py sdist upload``.
- ``python setup.py bdist_wheel upload``.
- ``python setup.py bdist_wheel upload``.
- Update conda-forge
- Update conda-forge
(https://github.com/conda-forge/pybind11-feedstock)
- change version number in ``meta.yml``
- change version number in ``meta.yml``
- update checksum to match the one computed by pypi
- update checksum to match the one computed by pypi
- Get back to work
- Get back to work
...
...
example/example11.cpp
View file @
178c8a89
...
@@ -19,11 +19,25 @@ void kw_func4(const std::vector<int> &entries) {
...
@@ -19,11 +19,25 @@ void kw_func4(const std::vector<int> &entries) {
std
::
cout
<<
endl
;
std
::
cout
<<
endl
;
}
}
void
call_kw_func
(
py
::
function
f
)
{
py
::
object
call_kw_func
(
py
::
function
f
)
{
py
::
tuple
args
=
py
::
make_tuple
(
1234
);
py
::
tuple
args
=
py
::
make_tuple
(
1234
);
py
::
dict
kwargs
;
py
::
dict
kwargs
;
kwargs
[
"y"
]
=
py
::
cast
(
5678
);
kwargs
[
"y"
]
=
py
::
cast
(
5678
);
f
(
*
args
,
**
kwargs
);
return
f
(
*
args
,
**
kwargs
);
}
void
args_function
(
py
::
args
args
)
{
for
(
auto
item
:
args
)
std
::
cout
<<
"got argument: "
<<
item
<<
std
::
endl
;
}
void
args_kwargs_function
(
py
::
args
args
,
py
::
kwargs
kwargs
)
{
for
(
auto
item
:
args
)
std
::
cout
<<
"got argument: "
<<
item
<<
std
::
endl
;
if
(
kwargs
)
{
for
(
auto
item
:
kwargs
)
std
::
cout
<<
"got keyword argument: "
<<
item
.
first
<<
" -> "
<<
item
.
second
<<
std
::
endl
;
}
}
}
void
init_ex11
(
py
::
module
&
m
)
{
void
init_ex11
(
py
::
module
&
m
)
{
...
@@ -38,4 +52,7 @@ void init_ex11(py::module &m) {
...
@@ -38,4 +52,7 @@ void init_ex11(py::module &m) {
m
.
def
(
"kw_func4"
,
&
kw_func4
,
py
::
arg
(
"myList"
)
=
list
);
m
.
def
(
"kw_func4"
,
&
kw_func4
,
py
::
arg
(
"myList"
)
=
list
);
m
.
def
(
"call_kw_func"
,
&
call_kw_func
);
m
.
def
(
"call_kw_func"
,
&
call_kw_func
);
m
.
def
(
"args_function"
,
&
args_function
);
m
.
def
(
"args_kwargs_function"
,
&
args_kwargs_function
);
}
}
example/example11.py
View file @
178c8a89
...
@@ -6,6 +6,7 @@ import pydoc
...
@@ -6,6 +6,7 @@ import pydoc
sys
.
path
.
append
(
'.'
)
sys
.
path
.
append
(
'.'
)
from
example
import
kw_func
,
kw_func2
,
kw_func3
,
kw_func4
,
call_kw_func
from
example
import
kw_func
,
kw_func2
,
kw_func3
,
kw_func4
,
call_kw_func
from
example
import
args_function
,
args_kwargs_function
print
(
pydoc
.
render_doc
(
kw_func
,
"Help on
%
s"
))
print
(
pydoc
.
render_doc
(
kw_func
,
"Help on
%
s"
))
print
(
pydoc
.
render_doc
(
kw_func2
,
"Help on
%
s"
))
print
(
pydoc
.
render_doc
(
kw_func2
,
"Help on
%
s"
))
...
@@ -32,6 +33,9 @@ except Exception as e:
...
@@ -32,6 +33,9 @@ except Exception as e:
print
(
"Caught expected exception: "
+
str
(
e
))
print
(
"Caught expected exception: "
+
str
(
e
))
kw_func4
()
kw_func4
()
kw_func4
(
myList
=
[
1
,
2
,
3
])
kw_func4
(
myList
=
[
1
,
2
,
3
])
call_kw_func
(
kw_func2
)
call_kw_func
(
kw_func2
)
args_function
(
'arg1_value'
,
'arg2_value'
,
3
)
args_kwargs_function
(
'arg1_value'
,
'arg2_value'
,
arg3
=
'arg3_value'
,
arg4
=
4
)
example/example11.ref
View file @
178c8a89
...
@@ -33,3 +33,10 @@ Caught expected exception: Incompatible function arguments. The following argume
...
@@ -33,3 +33,10 @@ Caught expected exception: Incompatible function arguments. The following argume
kw_func4: 13 17
kw_func4: 13 17
kw_func4: 1 2 3
kw_func4: 1 2 3
kw_func(x=1234, y=5678)
kw_func(x=1234, y=5678)
got argument: arg1_value
got argument: arg2_value
got argument: 3
got argument: arg1_value
got argument: arg2_value
got keyword argument: arg3 -> arg3_value
got keyword argument: arg4 -> 4
include/pybind11/attr.h
View file @
178c8a89
...
@@ -92,7 +92,7 @@ struct function_record {
...
@@ -92,7 +92,7 @@ struct function_record {
std
::
vector
<
argument_record
>
args
;
std
::
vector
<
argument_record
>
args
;
/// Pointer to lambda function which converts arguments and performs the actual call
/// Pointer to lambda function which converts arguments and performs the actual call
handle
(
*
impl
)
(
function_record
*
,
handle
,
handle
)
=
nullptr
;
handle
(
*
impl
)
(
function_record
*
,
handle
,
handle
,
handle
)
=
nullptr
;
/// Storage for the wrapped function pointer and captured data, if any
/// Storage for the wrapped function pointer and captured data, if any
void
*
data
[
3
]
=
{
};
void
*
data
[
3
]
=
{
};
...
@@ -104,7 +104,16 @@ struct function_record {
...
@@ -104,7 +104,16 @@ struct function_record {
return_value_policy
policy
=
return_value_policy
::
automatic
;
return_value_policy
policy
=
return_value_policy
::
automatic
;
/// True if name == '__init__'
/// True if name == '__init__'
bool
is_constructor
=
false
;
bool
is_constructor
:
1
;
/// True if the function has a '*args' argument
bool
has_args
:
1
;
/// True if the function has a '**kwargs' argument
bool
has_kwargs
:
1
;
/// Number of arguments
uint16_t
nargs
;
/// Python method object
/// Python method object
PyMethodDef
*
def
=
nullptr
;
PyMethodDef
*
def
=
nullptr
;
...
...
include/pybind11/cast.h
View file @
178c8a89
...
@@ -15,6 +15,7 @@
...
@@ -15,6 +15,7 @@
#include "descr.h"
#include "descr.h"
#include <array>
#include <array>
#include <limits>
#include <limits>
#include <iostream>
NAMESPACE_BEGIN
(
pybind11
)
NAMESPACE_BEGIN
(
pybind11
)
NAMESPACE_BEGIN
(
detail
)
NAMESPACE_BEGIN
(
detail
)
...
@@ -320,7 +321,9 @@ public:
...
@@ -320,7 +321,9 @@ public:
bool
load
(
handle
src
,
bool
)
{
bool
load
(
handle
src
,
bool
)
{
py_type
py_value
;
py_type
py_value
;
if
(
std
::
is_floating_point
<
T
>::
value
)
{
if
(
!
src
)
{
return
false
;
}
if
(
std
::
is_floating_point
<
T
>::
value
)
{
py_value
=
(
py_type
)
PyFloat_AsDouble
(
src
.
ptr
());
py_value
=
(
py_type
)
PyFloat_AsDouble
(
src
.
ptr
());
}
else
if
(
sizeof
(
T
)
<=
sizeof
(
long
))
{
}
else
if
(
sizeof
(
T
)
<=
sizeof
(
long
))
{
if
(
std
::
is_signed
<
T
>::
value
)
if
(
std
::
is_signed
<
T
>::
value
)
...
@@ -394,7 +397,9 @@ public:
...
@@ -394,7 +397,9 @@ public:
using
type_caster
<
void_type
>::
cast
;
using
type_caster
<
void_type
>::
cast
;
bool
load
(
handle
h
,
bool
)
{
bool
load
(
handle
h
,
bool
)
{
if
(
h
.
ptr
()
==
Py_None
)
{
if
(
!
h
)
{
return
false
;
}
else
if
(
h
.
ptr
()
==
Py_None
)
{
value
=
nullptr
;
value
=
nullptr
;
return
true
;
return
true
;
}
}
...
@@ -435,7 +440,8 @@ template <> class type_caster<std::nullptr_t> : public type_caster<void_type> {
...
@@ -435,7 +440,8 @@ template <> class type_caster<std::nullptr_t> : public type_caster<void_type> {
template
<>
class
type_caster
<
bool
>
{
template
<>
class
type_caster
<
bool
>
{
public
:
public
:
bool
load
(
handle
src
,
bool
)
{
bool
load
(
handle
src
,
bool
)
{
if
(
src
.
ptr
()
==
Py_True
)
{
value
=
true
;
return
true
;
}
if
(
!
src
)
return
false
;
else
if
(
src
.
ptr
()
==
Py_True
)
{
value
=
true
;
return
true
;
}
else
if
(
src
.
ptr
()
==
Py_False
)
{
value
=
false
;
return
true
;
}
else
if
(
src
.
ptr
()
==
Py_False
)
{
value
=
false
;
return
true
;
}
else
return
false
;
else
return
false
;
}
}
...
@@ -450,7 +456,9 @@ public:
...
@@ -450,7 +456,9 @@ public:
bool
load
(
handle
src
,
bool
)
{
bool
load
(
handle
src
,
bool
)
{
object
temp
;
object
temp
;
handle
load_src
=
src
;
handle
load_src
=
src
;
if
(
PyUnicode_Check
(
load_src
.
ptr
()))
{
if
(
!
src
)
{
return
false
;
}
else
if
(
PyUnicode_Check
(
load_src
.
ptr
()))
{
temp
=
object
(
PyUnicode_AsUTF8String
(
load_src
.
ptr
()),
false
);
temp
=
object
(
PyUnicode_AsUTF8String
(
load_src
.
ptr
()),
false
);
if
(
!
temp
)
{
PyErr_Clear
();
return
false
;
}
// UnicodeEncodeError
if
(
!
temp
)
{
PyErr_Clear
();
return
false
;
}
// UnicodeEncodeError
load_src
=
temp
;
load_src
=
temp
;
...
@@ -489,7 +497,9 @@ public:
...
@@ -489,7 +497,9 @@ public:
bool
load
(
handle
src
,
bool
)
{
bool
load
(
handle
src
,
bool
)
{
object
temp
;
object
temp
;
handle
load_src
=
src
;
handle
load_src
=
src
;
if
(
!
PyUnicode_Check
(
load_src
.
ptr
()))
{
if
(
!
src
)
{
return
false
;
}
else
if
(
!
PyUnicode_Check
(
load_src
.
ptr
()))
{
temp
=
object
(
PyUnicode_FromObject
(
load_src
.
ptr
()),
false
);
temp
=
object
(
PyUnicode_FromObject
(
load_src
.
ptr
()),
false
);
if
(
!
temp
)
{
PyErr_Clear
();
return
false
;
}
if
(
!
temp
)
{
PyErr_Clear
();
return
false
;
}
load_src
=
temp
;
load_src
=
temp
;
...
@@ -527,7 +537,7 @@ protected:
...
@@ -527,7 +537,7 @@ protected:
template
<>
class
type_caster
<
char
>
:
public
type_caster
<
std
::
string
>
{
template
<>
class
type_caster
<
char
>
:
public
type_caster
<
std
::
string
>
{
public
:
public
:
bool
load
(
handle
src
,
bool
convert
)
{
bool
load
(
handle
src
,
bool
convert
)
{
if
(
src
.
ptr
()
==
Py_None
)
{
return
true
;
}
if
(
src
.
ptr
()
==
Py_None
)
return
true
;
return
type_caster
<
std
::
string
>::
load
(
src
,
convert
);
return
type_caster
<
std
::
string
>::
load
(
src
,
convert
);
}
}
...
@@ -550,7 +560,7 @@ public:
...
@@ -550,7 +560,7 @@ public:
template
<>
class
type_caster
<
wchar_t
>
:
public
type_caster
<
std
::
wstring
>
{
template
<>
class
type_caster
<
wchar_t
>
:
public
type_caster
<
std
::
wstring
>
{
public
:
public
:
bool
load
(
handle
src
,
bool
convert
)
{
bool
load
(
handle
src
,
bool
convert
)
{
if
(
src
.
ptr
()
==
Py_None
)
{
return
true
;
}
if
(
src
.
ptr
()
==
Py_None
)
return
true
;
return
type_caster
<
std
::
wstring
>::
load
(
src
,
convert
);
return
type_caster
<
std
::
wstring
>::
load
(
src
,
convert
);
}
}
...
@@ -574,7 +584,9 @@ template <typename T1, typename T2> class type_caster<std::pair<T1, T2>> {
...
@@ -574,7 +584,9 @@ template <typename T1, typename T2> class type_caster<std::pair<T1, T2>> {
typedef
std
::
pair
<
T1
,
T2
>
type
;
typedef
std
::
pair
<
T1
,
T2
>
type
;
public
:
public
:
bool
load
(
handle
src
,
bool
convert
)
{
bool
load
(
handle
src
,
bool
convert
)
{
if
(
!
PyTuple_Check
(
src
.
ptr
())
||
PyTuple_Size
(
src
.
ptr
())
!=
2
)
if
(
!
src
)
return
false
;
else
if
(
!
PyTuple_Check
(
src
.
ptr
())
||
PyTuple_Size
(
src
.
ptr
())
!=
2
)
return
false
;
return
false
;
return
first
.
load
(
PyTuple_GET_ITEM
(
src
.
ptr
(),
0
),
convert
)
&&
return
first
.
load
(
PyTuple_GET_ITEM
(
src
.
ptr
(),
0
),
convert
)
&&
second
.
load
(
PyTuple_GET_ITEM
(
src
.
ptr
(),
1
),
convert
);
second
.
load
(
PyTuple_GET_ITEM
(
src
.
ptr
(),
1
),
convert
);
...
@@ -610,13 +622,41 @@ protected:
...
@@ -610,13 +622,41 @@ protected:
template
<
typename
...
Tuple
>
class
type_caster
<
std
::
tuple
<
Tuple
...
>>
{
template
<
typename
...
Tuple
>
class
type_caster
<
std
::
tuple
<
Tuple
...
>>
{
typedef
std
::
tuple
<
Tuple
...
>
type
;
typedef
std
::
tuple
<
Tuple
...
>
type
;
typedef
std
::
tuple
<
typename
intrinsic_type
<
Tuple
>::
type
...
>
itype
;
typedef
std
::
tuple
<
args
>
args_type
;
typedef
std
::
tuple
<
args
,
kwargs
>
args_kwargs_type
;
public
:
public
:
enum
{
size
=
sizeof
...(
Tuple
)
};
enum
{
size
=
sizeof
...(
Tuple
)
};
static
constexpr
const
bool
has_kwargs
=
std
::
is_same
<
itype
,
args_kwargs_type
>::
value
;
static
constexpr
const
bool
has_args
=
has_kwargs
||
std
::
is_same
<
itype
,
args_type
>::
value
;
bool
load
(
handle
src
,
bool
convert
)
{
bool
load
(
handle
src
,
bool
convert
)
{
if
(
!
src
||
!
PyTuple_Check
(
src
.
ptr
())
||
PyTuple_GET_SIZE
(
src
.
ptr
())
!=
size
)
return
false
;
return
load
(
src
,
convert
,
typename
make_index_sequence
<
sizeof
...(
Tuple
)
>::
type
());
return
load
(
src
,
convert
,
typename
make_index_sequence
<
sizeof
...(
Tuple
)
>::
type
());
}
}
template
<
typename
T
=
itype
,
typename
std
::
enable_if
<
!
std
::
is_same
<
T
,
args_type
>::
value
&&
!
std
::
is_same
<
T
,
args_kwargs_type
>::
value
,
int
>::
type
=
0
>
bool
load_args
(
handle
args
,
handle
,
bool
convert
)
{
return
load
(
args
,
convert
,
typename
make_index_sequence
<
sizeof
...(
Tuple
)
>::
type
());
}
template
<
typename
T
=
itype
,
typename
std
::
enable_if
<
std
::
is_same
<
T
,
args_type
>::
value
,
int
>::
type
=
0
>
bool
load_args
(
handle
args
,
handle
,
bool
convert
)
{
std
::
get
<
0
>
(
value
).
load
(
args
,
convert
);
return
true
;
}
template
<
typename
T
=
itype
,
typename
std
::
enable_if
<
std
::
is_same
<
T
,
args_kwargs_type
>::
value
,
int
>::
type
=
0
>
bool
load_args
(
handle
args
,
handle
kwargs
,
bool
convert
)
{
std
::
get
<
0
>
(
value
).
load
(
args
,
convert
);
std
::
get
<
1
>
(
value
).
load
(
kwargs
,
convert
);
return
true
;
}
static
handle
cast
(
const
type
&
src
,
return_value_policy
policy
,
handle
parent
)
{
static
handle
cast
(
const
type
&
src
,
return_value_policy
policy
,
handle
parent
)
{
return
cast
(
src
,
policy
,
parent
,
typename
make_index_sequence
<
size
>::
type
());
return
cast
(
src
,
policy
,
parent
,
typename
make_index_sequence
<
size
>::
type
());
}
}
...
@@ -655,10 +695,8 @@ protected:
...
@@ -655,10 +695,8 @@ protected:
}
}
template
<
size_t
...
Indices
>
bool
load
(
handle
src
,
bool
convert
,
index_sequence
<
Indices
...
>
)
{
template
<
size_t
...
Indices
>
bool
load
(
handle
src
,
bool
convert
,
index_sequence
<
Indices
...
>
)
{
if
(
!
PyTuple_Check
(
src
.
ptr
())
||
PyTuple_Size
(
src
.
ptr
())
!=
size
)
return
false
;
std
::
array
<
bool
,
size
>
success
{{
std
::
array
<
bool
,
size
>
success
{{
(
PyTuple_GET_ITEM
(
src
.
ptr
(),
Indices
)
!=
nullptr
?
std
::
get
<
Indices
>
(
value
).
load
(
PyTuple_GET_ITEM
(
src
.
ptr
(),
Indices
),
convert
)
:
false
)...
std
::
get
<
Indices
>
(
value
).
load
(
PyTuple_GET_ITEM
(
src
.
ptr
(),
Indices
),
convert
)...
}};
}};
(
void
)
convert
;
/* avoid a warning when the tuple is empty */
(
void
)
convert
;
/* avoid a warning when the tuple is empty */
for
(
bool
r
:
success
)
for
(
bool
r
:
success
)
...
@@ -742,14 +780,16 @@ protected:
...
@@ -742,14 +780,16 @@ protected:
template
<
typename
T
>
struct
handle_type_name
{
static
PYBIND11_DESCR
name
()
{
return
_
<
T
>
();
}
};
template
<
typename
T
>
struct
handle_type_name
{
static
PYBIND11_DESCR
name
()
{
return
_
<
T
>
();
}
};
template
<>
struct
handle_type_name
<
bytes
>
{
static
PYBIND11_DESCR
name
()
{
return
_
(
PYBIND11_BYTES_NAME
);
}
};
template
<>
struct
handle_type_name
<
bytes
>
{
static
PYBIND11_DESCR
name
()
{
return
_
(
PYBIND11_BYTES_NAME
);
}
};
template
<>
struct
handle_type_name
<
args
>
{
static
PYBIND11_DESCR
name
()
{
return
_
(
"*args"
);
}
};
template
<>
struct
handle_type_name
<
kwargs
>
{
static
PYBIND11_DESCR
name
()
{
return
_
(
"**kwargs"
);
}
};
template
<
typename
type
>
template
<
typename
type
>
struct
type_caster
<
type
,
typename
std
::
enable_if
<
std
::
is_base_of
<
handle
,
type
>::
value
>::
type
>
{
struct
type_caster
<
type
,
typename
std
::
enable_if
<
std
::
is_base_of
<
handle
,
type
>::
value
>::
type
>
{
public
:
public
:
template
<
typename
T
=
type
,
typename
std
::
enable_if
<
std
::
is_same
<
T
,
handle
>::
value
,
int
>::
type
=
0
>
template
<
typename
T
=
type
,
typename
std
::
enable_if
<
!
std
::
is_base_of
<
object
,
T
>::
value
,
int
>::
type
=
0
>
bool
load
(
handle
src
,
bool
/* convert */
)
{
value
=
src
;
return
value
.
check
();
}
bool
load
(
handle
src
,
bool
/* convert */
)
{
value
=
type
(
src
)
;
return
value
.
check
();
}
template
<
typename
T
=
type
,
typename
std
::
enable_if
<
!
std
::
is_same
<
T
,
handle
>::
value
,
int
>::
type
=
0
>
template
<
typename
T
=
type
,
typename
std
::
enable_if
<
std
::
is_base_of
<
object
,
T
>::
value
,
int
>::
type
=
0
>
bool
load
(
handle
src
,
bool
/* convert */
)
{
value
=
type
(
src
,
true
);
return
value
.
check
();
}
bool
load
(
handle
src
,
bool
/* convert */
)
{
value
=
type
(
src
,
true
);
return
value
.
check
();
}
static
handle
cast
(
const
handle
&
src
,
return_value_policy
/* policy */
,
handle
/* parent */
)
{
static
handle
cast
(
const
handle
&
src
,
return_value_policy
/* policy */
,
handle
/* parent */
)
{
...
@@ -768,7 +808,9 @@ template <typename T> T cast(handle handle) {
...
@@ -768,7 +808,9 @@ template <typename T> T cast(handle handle) {
return
conv
.
operator
typename
type_caster
::
template
cast_op_type
<
T
>
();
return
conv
.
operator
typename
type_caster
::
template
cast_op_type
<
T
>
();
}
}
template
<
typename
T
>
object
cast
(
const
T
&
value
,
return_value_policy
policy
=
return_value_policy
::
automatic_reference
,
handle
parent
=
handle
())
{
template
<
typename
T
>
object
cast
(
const
T
&
value
,
return_value_policy
policy
=
return_value_policy
::
automatic_reference
,
handle
parent
=
handle
())
{
if
(
policy
==
return_value_policy
::
automatic
)
if
(
policy
==
return_value_policy
::
automatic
)
policy
=
std
::
is_pointer
<
T
>::
value
?
return_value_policy
::
take_ownership
:
return_value_policy
::
copy
;
policy
=
std
::
is_pointer
<
T
>::
value
?
return_value_policy
::
take_ownership
:
return_value_policy
::
copy
;
else
if
(
policy
==
return_value_policy
::
automatic_reference
)
else
if
(
policy
==
return_value_policy
::
automatic_reference
)
...
@@ -808,14 +850,14 @@ template <typename... Args> object handle::call(Args &&... args) const {
...
@@ -808,14 +850,14 @@ template <typename... Args> object handle::call(Args &&... args) const {
return
operator
()(
std
::
forward
<
Args
>
(
args
)...);
return
operator
()(
std
::
forward
<
Args
>
(
args
)...);
}
}
inline
object
handle
::
operator
()(
detail
::
args
args
)
const
{
inline
object
handle
::
operator
()(
detail
::
args
_proxy
args
)
const
{
object
result
(
PyObject_CallObject
(
m_ptr
,
args
.
ptr
()),
false
);
object
result
(
PyObject_CallObject
(
m_ptr
,
args
.
ptr
()),
false
);
if
(
!
result
)
if
(
!
result
)
throw
error_already_set
();
throw
error_already_set
();
return
result
;
return
result
;
}
}
inline
object
handle
::
operator
()(
detail
::
args
args
,
detail
::
kwargs
kwargs
)
const
{
inline
object
handle
::
operator
()(
detail
::
args
_proxy
args
,
detail
::
kwargs_proxy
kwargs
)
const
{
object
result
(
PyObject_Call
(
m_ptr
,
args
.
ptr
(),
kwargs
.
ptr
()),
false
);
object
result
(
PyObject_Call
(
m_ptr
,
args
.
ptr
(),
kwargs
.
ptr
()),
false
);
if
(
!
result
)
if
(
!
result
)
throw
error_already_set
();
throw
error_already_set
();
...
...
include/pybind11/common.h
View file @
178c8a89
...
@@ -142,7 +142,7 @@ NAMESPACE_BEGIN(pybind11)
...
@@ -142,7 +142,7 @@ NAMESPACE_BEGIN(pybind11)
typedef
Py_ssize_t
ssize_t
;
typedef
Py_ssize_t
ssize_t
;
/// Approach used to cast a previously unknown C++ instance into a Python object
/// Approach used to cast a previously unknown C++ instance into a Python object
enum
class
return_value_policy
:
in
t
{
enum
class
return_value_policy
:
uint8_
t
{
/** This is the default return value policy, which falls back to the policy
/** This is the default return value policy, which falls back to the policy
return_value_policy::take_ownership when the return value is a pointer.
return_value_policy::take_ownership when the return value is a pointer.
Otherwise, it uses return_value::move or return_value::copy for rvalue
Otherwise, it uses return_value::move or return_value::copy for rvalue
...
...
include/pybind11/complex.h
View file @
178c8a89
...
@@ -26,6 +26,8 @@ NAMESPACE_BEGIN(detail)
...
@@ -26,6 +26,8 @@ NAMESPACE_BEGIN(detail)
template
<
typename
T
>
class
type_caster
<
std
::
complex
<
T
>>
{
template
<
typename
T
>
class
type_caster
<
std
::
complex
<
T
>>
{
public
:
public
:
bool
load
(
handle
src
,
bool
)
{
bool
load
(
handle
src
,
bool
)
{
if
(
!
src
)
return
false
;
Py_complex
result
=
PyComplex_AsCComplex
(
src
.
ptr
());
Py_complex
result
=
PyComplex_AsCComplex
(
src
.
ptr
());
if
(
result
.
real
==
-
1
.
0
&&
PyErr_Occurred
())
{
if
(
result
.
real
==
-
1
.
0
&&
PyErr_Occurred
())
{
PyErr_Clear
();
PyErr_Clear
();
...
...
include/pybind11/eigen.h
View file @
178c8a89
...
@@ -138,6 +138,9 @@ struct type_caster<Type, typename std::enable_if<is_eigen_sparse<Type>::value>::
...
@@ -138,6 +138,9 @@ struct type_caster<Type, typename std::enable_if<is_eigen_sparse<Type>::value>::
static
constexpr
bool
rowMajor
=
Type
::
Flags
&
Eigen
::
RowMajorBit
;
static
constexpr
bool
rowMajor
=
Type
::
Flags
&
Eigen
::
RowMajorBit
;
bool
load
(
handle
src
,
bool
)
{
bool
load
(
handle
src
,
bool
)
{
if
(
!
src
)
return
false
;
object
obj
(
src
,
true
);
object
obj
(
src
,
true
);
object
sparse_module
=
module
::
import
(
"scipy.sparse"
);
object
sparse_module
=
module
::
import
(
"scipy.sparse"
);
object
matrix_type
=
sparse_module
.
attr
(
object
matrix_type
=
sparse_module
.
attr
(
...
...
include/pybind11/pybind11.h
View file @
178c8a89
...
@@ -92,11 +92,11 @@ protected:
...
@@ -92,11 +92,11 @@ protected:
typename
detail
::
intrinsic_type
<
Return
>::
type
>::
type
>
cast_out
;
typename
detail
::
intrinsic_type
<
Return
>::
type
>::
type
>
cast_out
;
/* Dispatch code which converts function arguments and performs the actual function call */
/* Dispatch code which converts function arguments and performs the actual function call */
rec
->
impl
=
[](
detail
::
function_record
*
rec
,
handle
args
,
handle
parent
)
->
handle
{
rec
->
impl
=
[](
detail
::
function_record
*
rec
,
handle
args
,
handle
kwargs
,
handle
parent
)
->
handle
{
cast_in
args_converter
;
cast_in
args_converter
;
/* Try to cast the function arguments into the C++ domain */
/* Try to cast the function arguments into the C++ domain */
if
(
!
args_converter
.
load
(
args
,
true
))
if
(
!
args_converter
.
load
_args
(
args
,
kw
args
,
true
))
return
PYBIND11_TRY_NEXT_OVERLOAD
;
return
PYBIND11_TRY_NEXT_OVERLOAD
;
/* Invoke call policy pre-call hook */
/* Invoke call policy pre-call hook */
...
@@ -106,7 +106,7 @@ protected:
...
@@ -106,7 +106,7 @@ protected:
capture
*
cap
=
(
capture
*
)
(
sizeof
(
capture
)
<=
sizeof
(
rec
->
data
)
capture
*
cap
=
(
capture
*
)
(
sizeof
(
capture
)
<=
sizeof
(
rec
->
data
)
?
&
rec
->
data
:
rec
->
data
[
0
]);
?
&
rec
->
data
:
rec
->
data
[
0
]);
/* Perform the functionc
all */
/* Perform the functioncall */
handle
result
=
cast_out
::
cast
(
args_converter
.
template
call
<
Return
>
(
cap
->
f
),
handle
result
=
cast_out
::
cast
(
args_converter
.
template
call
<
Return
>
(
cap
->
f
),
rec
->
policy
,
parent
);
rec
->
policy
,
parent
);
...
@@ -125,6 +125,9 @@ protected:
...
@@ -125,6 +125,9 @@ protected:
/* Register the function with Python from generic (non-templated) code */
/* Register the function with Python from generic (non-templated) code */
initialize_generic
(
rec
,
signature
.
text
(),
signature
.
types
(),
sizeof
...(
Args
));
initialize_generic
(
rec
,
signature
.
text
(),
signature
.
types
(),
sizeof
...(
Args
));
if
(
cast_in
::
has_args
)
rec
->
has_args
=
true
;
if
(
cast_in
::
has_kwargs
)
rec
->
has_kwargs
=
true
;
}
}
/// Register a function call with Python (generic non-templated code goes here)
/// Register a function call with Python (generic non-templated code goes here)
...
@@ -204,9 +207,12 @@ protected:
...
@@ -204,9 +207,12 @@ protected:
std
::
to_string
(
args
)
+
" arguments, but "
+
std
::
to_string
(
rec
->
args
.
size
())
+
std
::
to_string
(
args
)
+
" arguments, but "
+
std
::
to_string
(
rec
->
args
.
size
())
+
" pybind11::arg entries were specified!"
);
" pybind11::arg entries were specified!"
);
rec
->
is_constructor
=
!
strcmp
(
rec
->
name
,
"__init__"
);
rec
->
signature
=
strdup
(
signature
.
c_str
());
rec
->
signature
=
strdup
(
signature
.
c_str
());
rec
->
args
.
shrink_to_fit
();
rec
->
args
.
shrink_to_fit
();
rec
->
is_constructor
=
!
strcmp
(
rec
->
name
,
"__init__"
);
rec
->
has_args
=
false
;
rec
->
has_kwargs
=
false
;
rec
->
nargs
=
args
;
#if PY_MAJOR_VERSION < 3
#if PY_MAJOR_VERSION < 3
if
(
rec
->
sibling
&&
PyMethod_Check
(
rec
->
sibling
.
ptr
()))
if
(
rec
->
sibling
&&
PyMethod_Check
(
rec
->
sibling
.
ptr
()))
...
@@ -325,15 +331,15 @@ protected:
...
@@ -325,15 +331,15 @@ protected:
*
it
=
overloads
;
*
it
=
overloads
;
/* Need to know how many arguments + keyword arguments there are to pick the right overload */
/* Need to know how many arguments + keyword arguments there are to pick the right overload */
int
nargs
=
(
int
)
PyTuple_Size
(
args
),
size_t
nargs
=
PyTuple_GET_SIZE
(
args
),
nkwargs
=
kwargs
?
(
int
)
PyDict_Size
(
kwargs
)
:
0
;
nkwargs
=
kwargs
?
PyDict_Size
(
kwargs
)
:
0
;
handle
parent
=
nargs
>
0
?
PyTuple_G
etItem
(
args
,
0
)
:
nullptr
,
handle
parent
=
nargs
>
0
?
PyTuple_G
ET_ITEM
(
args
,
0
)
:
nullptr
,
result
=
PYBIND11_TRY_NEXT_OVERLOAD
;
result
=
PYBIND11_TRY_NEXT_OVERLOAD
;
try
{
try
{
for
(;
it
!=
nullptr
;
it
=
it
->
next
)
{
for
(;
it
!=
nullptr
;
it
=
it
->
next
)
{
tuple
args_
(
args
,
true
);
tuple
args_
(
args
,
true
);
in
t
kwargs_consumed
=
0
;
size_
t
kwargs_consumed
=
0
;
/* For each overload:
/* For each overload:
1. If the required list of arguments is longer than the
1. If the required list of arguments is longer than the
...
@@ -342,10 +348,11 @@ protected:
...
@@ -342,10 +348,11 @@ protected:
2. Ensure that all keyword arguments were "consumed"
2. Ensure that all keyword arguments were "consumed"
3. Call the function call dispatcher (function_record::impl)
3. Call the function call dispatcher (function_record::impl)
*/
*/
size_t
nargs_
=
nargs
;
if
(
nargs
<
(
int
)
it
->
args
.
size
())
{
if
(
nargs
<
it
->
args
.
size
())
{
args_
=
tuple
(
it
->
args
.
size
());
nargs_
=
it
->
args
.
size
();
for
(
int
i
=
0
;
i
<
nargs
;
++
i
)
{
args_
=
tuple
(
nargs_
);
for
(
size_t
i
=
0
;
i
<
nargs
;
++
i
)
{
handle
item
=
PyTuple_GET_ITEM
(
args
,
i
);
handle
item
=
PyTuple_GET_ITEM
(
args
,
i
);
PyTuple_SET_ITEM
(
args_
.
ptr
(),
i
,
item
.
inc_ref
().
ptr
());
PyTuple_SET_ITEM
(
args_
.
ptr
(),
i
,
item
.
inc_ref
().
ptr
());
}
}
...
@@ -368,15 +375,16 @@ protected:
...
@@ -368,15 +375,16 @@ protected:
if
(
value
)
{
if
(
value
)
{
PyTuple_SET_ITEM
(
args_
.
ptr
(),
index
,
value
.
inc_ref
().
ptr
());
PyTuple_SET_ITEM
(
args_
.
ptr
(),
index
,
value
.
inc_ref
().
ptr
());
}
else
{
}
else
{
kwargs_consumed
=
-
1
;
/* definite failure */
kwargs_consumed
=
(
size_t
)
-
1
;
/* definite failure */
break
;
break
;
}
}
}
}
}
}
try
{
try
{
if
(
kwargs_consumed
==
nkwargs
)
if
((
kwargs_consumed
==
nkwargs
||
it
->
has_kwargs
)
&&
result
=
it
->
impl
(
it
,
args_
,
parent
);
(
nargs_
==
it
->
nargs
||
it
->
has_args
))
result
=
it
->
impl
(
it
,
args_
,
kwargs
,
parent
);
}
catch
(
cast_error
&
)
{
}
catch
(
cast_error
&
)
{
result
=
PYBIND11_TRY_NEXT_OVERLOAD
;
result
=
PYBIND11_TRY_NEXT_OVERLOAD
;
}
}
...
@@ -420,7 +428,7 @@ protected:
...
@@ -420,7 +428,7 @@ protected:
if
(
overloads
->
is_constructor
)
{
if
(
overloads
->
is_constructor
)
{
/* When a constructor ran successfully, the corresponding
/* When a constructor ran successfully, the corresponding
holder type (e.g. std::unique_ptr) must still be initialized. */
holder type (e.g. std::unique_ptr) must still be initialized. */
PyObject
*
inst
=
PyTuple_G
etItem
(
args
,
0
);
PyObject
*
inst
=
PyTuple_G
ET_ITEM
(
args
,
0
);
auto
tinfo
=
detail
::
get_type_info
(
Py_TYPE
(
inst
));
auto
tinfo
=
detail
::
get_type_info
(
Py_TYPE
(
inst
));
tinfo
->
init_holder
(
inst
,
nullptr
);
tinfo
->
init_holder
(
inst
,
nullptr
);
}
}
...
...
include/pybind11/pytypes.h
View file @
178c8a89
...
@@ -16,12 +16,8 @@
...
@@ -16,12 +16,8 @@
NAMESPACE_BEGIN
(
pybind11
)
NAMESPACE_BEGIN
(
pybind11
)
/* A few forward declarations */
/* A few forward declarations */
class
object
;
class
object
;
class
str
;
class
object
;
class
dict
;
class
iterator
;
class
str
;
namespace
detail
{
class
accessor
;
class
args_proxy
;
class
kwargs_proxy
;
}
class
object
;
class
dict
;
class
iterator
;
namespace
detail
{
class
accessor
;
class
args
;
class
kwargs
;
}
/// Holds a reference to a Python object (no reference counting)
/// Holds a reference to a Python object (no reference counting)
class
handle
{
class
handle
{
...
@@ -43,17 +39,17 @@ public:
...
@@ -43,17 +39,17 @@ public:
inline
detail
::
accessor
attr
(
const
char
*
key
)
const
;
inline
detail
::
accessor
attr
(
const
char
*
key
)
const
;
inline
pybind11
::
str
str
()
const
;
inline
pybind11
::
str
str
()
const
;
template
<
typename
T
>
T
cast
()
const
;
template
<
typename
T
>
T
cast
()
const
;
template
<
typename
...
Args
>
template
<
typename
...
Args
>
[[
deprecated
(
"call(...) was deprecated in favor of operator()(...)"
)]]
[[
deprecated
(
"call(...) was deprecated in favor of operator()(...)"
)]]
object
call
(
Args
&&
...
args
)
const
;
object
call
(
Args
&&
...
args
)
const
;
template
<
typename
...
Args
>
object
operator
()(
Args
&&
...
args
)
const
;
template
<
typename
...
Args
>
object
operator
()(
Args
&&
...
args
)
const
;
inline
object
operator
()(
detail
::
args
args
)
const
;
inline
object
operator
()(
detail
::
args
_proxy
args
)
const
;
inline
object
operator
()(
detail
::
args
args
,
detail
::
kwargs
kwargs
)
const
;
inline
object
operator
()(
detail
::
args
_proxy
f_args
,
detail
::
kwargs_proxy
kwargs
)
const
;
operator
bool
()
const
{
return
m_ptr
!=
nullptr
;
}
operator
bool
()
const
{
return
m_ptr
!=
nullptr
;
}
bool
operator
==
(
const
handle
&
h
)
const
{
return
m_ptr
==
h
.
m_ptr
;
}
bool
operator
==
(
const
handle
&
h
)
const
{
return
m_ptr
==
h
.
m_ptr
;
}
bool
operator
!=
(
const
handle
&
h
)
const
{
return
m_ptr
!=
h
.
m_ptr
;
}
bool
operator
!=
(
const
handle
&
h
)
const
{
return
m_ptr
!=
h
.
m_ptr
;
}
bool
check
()
const
{
return
m_ptr
!=
nullptr
;
}
bool
check
()
const
{
return
m_ptr
!=
nullptr
;
}
inline
detail
::
args
operator
*
()
const
;
inline
detail
::
args
_proxy
operator
*
()
const
;
protected
:
protected
:
PyObject
*
m_ptr
;
PyObject
*
m_ptr
;
};
};
...
@@ -218,17 +214,6 @@ private:
...
@@ -218,17 +214,6 @@ private:
ssize_t
pos
=
0
;
ssize_t
pos
=
0
;
};
};
class
kwargs
:
public
handle
{
public
:
kwargs
(
handle
h
)
:
handle
(
h
)
{
}
};
class
args
:
public
handle
{
public
:
args
(
handle
h
)
:
handle
(
h
)
{
}
kwargs
operator
*
()
const
{
return
kwargs
(
*
this
);
}
};
inline
bool
PyIterable_Check
(
PyObject
*
obj
)
{
inline
bool
PyIterable_Check
(
PyObject
*
obj
)
{
PyObject
*
iter
=
PyObject_GetIter
(
obj
);
PyObject
*
iter
=
PyObject_GetIter
(
obj
);
if
(
iter
)
{
if
(
iter
)
{
...
@@ -239,20 +224,32 @@ inline bool PyIterable_Check(PyObject *obj) {
...
@@ -239,20 +224,32 @@ inline bool PyIterable_Check(PyObject *obj) {
return
false
;
return
false
;
}
}
}
}
inline
bool
PyNone_Check
(
PyObject
*
o
)
{
return
o
==
Py_None
;
}
inline
bool
PyNone_Check
(
PyObject
*
o
)
{
return
o
==
Py_None
;
}
inline
bool
PyUnicode_Check_Permissive
(
PyObject
*
o
)
{
return
PyUnicode_Check
(
o
)
||
PYBIND11_BYTES_CHECK
(
o
);
}
inline
bool
PyUnicode_Check_Permissive
(
PyObject
*
o
)
{
return
PyUnicode_Check
(
o
)
||
PYBIND11_BYTES_CHECK
(
o
);
}
class
kwargs_proxy
:
public
handle
{
public
:
kwargs_proxy
(
handle
h
)
:
handle
(
h
)
{
}
};
class
args_proxy
:
public
handle
{
public
:
args_proxy
(
handle
h
)
:
handle
(
h
)
{
}
kwargs_proxy
operator
*
()
const
{
return
kwargs_proxy
(
*
this
);
}
};
NAMESPACE_END
(
detail
)
NAMESPACE_END
(
detail
)
#define PYBIND11_OBJECT_CVT(Name, Parent, CheckFun, CvtStmt) \
#define PYBIND11_OBJECT_CVT(Name, Parent, CheckFun, CvtStmt) \
Name(const handle &h, bool borrowed) : Parent(h, borrowed) { CvtStmt; } \
public: \
Name(const object& o): Parent(o) { CvtStmt; } \
Name(const handle &h, bool borrowed) : Parent(h, borrowed) { CvtStmt; } \
Name(object&& o) noexcept : Parent(std::move(o)) { CvtStmt; } \
Name(const object& o): Parent(o) { CvtStmt; } \
Name& operator=(object&& o) noexcept { (void) object::operator=(std::move(o)); CvtStmt; return *this; } \
Name(object&& o) noexcept : Parent(std::move(o)) { CvtStmt; } \
Name& operator=(const object& o) { return static_cast<Name&>(object::operator=(o)); CvtStmt; } \
Name& operator=(object&& o) noexcept { (void) object::operator=(std::move(o)); CvtStmt; return *this; } \
bool check() const { return m_ptr != nullptr && (bool) CheckFun(m_ptr); }
Name& operator=(const object& o) { return static_cast<Name&>(object::operator=(o)); CvtStmt; } \
bool check() const { return m_ptr != nullptr && (bool) CheckFun(m_ptr); }
#define PYBIND11_OBJECT(Name, Parent, CheckFun) \
#define PYBIND11_OBJECT(Name, Parent, CheckFun) \
PYBIND11_OBJECT_CVT(Name, Parent, CheckFun, )
PYBIND11_OBJECT_CVT(Name, Parent, CheckFun, )
...
@@ -332,7 +329,7 @@ inline detail::accessor handle::attr(handle key) const { return detail::accessor
...
@@ -332,7 +329,7 @@ inline detail::accessor handle::attr(handle key) const { return detail::accessor
inline
detail
::
accessor
handle
::
attr
(
const
char
*
key
)
const
{
return
detail
::
accessor
(
ptr
(),
key
,
true
);
}
inline
detail
::
accessor
handle
::
attr
(
const
char
*
key
)
const
{
return
detail
::
accessor
(
ptr
(),
key
,
true
);
}
inline
iterator
handle
::
begin
()
const
{
return
iterator
(
PyObject_GetIter
(
ptr
()),
false
);
}
inline
iterator
handle
::
begin
()
const
{
return
iterator
(
PyObject_GetIter
(
ptr
()),
false
);
}
inline
iterator
handle
::
end
()
const
{
return
iterator
(
nullptr
,
false
);
}
inline
iterator
handle
::
end
()
const
{
return
iterator
(
nullptr
,
false
);
}
inline
detail
::
args
handle
::
operator
*
()
const
{
return
detail
::
args
(
*
this
);
}
inline
detail
::
args
_proxy
handle
::
operator
*
()
const
{
return
detail
::
args_proxy
(
*
this
);
}
class
str
:
public
object
{
class
str
:
public
object
{
public
:
public
:
...
@@ -520,6 +517,9 @@ public:
...
@@ -520,6 +517,9 @@ public:
void
append
(
const
object
&
object
)
const
{
PyList_Append
(
m_ptr
,
object
.
ptr
());
}
void
append
(
const
object
&
object
)
const
{
PyList_Append
(
m_ptr
,
object
.
ptr
());
}
};
};
class
args
:
public
list
{
PYBIND11_OBJECT_DEFAULT
(
args
,
list
,
PyList_Check
)
};
class
kwargs
:
public
dict
{
PYBIND11_OBJECT_DEFAULT
(
kwargs
,
dict
,
PyDict_Check
)
};
class
set
:
public
object
{
class
set
:
public
object
{
public
:
public
:
PYBIND11_OBJECT
(
set
,
object
,
PySet_Check
)
PYBIND11_OBJECT
(
set
,
object
,
PySet_Check
)
...
...
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