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
9309b022
Commit
9309b022
authored
May 28, 2016
by
Boris Schäling
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into cygwin
parents
20ee9352
2c76c693
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
172 additions
and
66 deletions
+172
-66
docs/advanced.rst
+20
-16
docs/changelog.rst
+11
-0
docs/conf.py
+2
-2
docs/release.rst
+2
-1
example/example11.cpp
+2
-2
example/example11.ref
+1
-1
example/example12.cpp
+4
-8
example/example12.ref
+1
-1
example/example14.ref
+1
-1
example/example5.ref
+1
-1
example/issues.cpp
+25
-2
example/issues.py
+17
-0
example/issues.ref
+9
-3
include/pybind11/attr.h
+1
-0
include/pybind11/cast.h
+1
-1
include/pybind11/eigen.h
+3
-3
include/pybind11/pybind11.h
+64
-17
include/pybind11/pytypes.h
+7
-7
No files found.
docs/advanced.rst
View file @
9309b022
...
@@ -268,8 +268,14 @@ helper class that is defined as follows:
...
@@ -268,8 +268,14 @@ helper class that is defined as follows:
The macro :func:`PYBIND11_OVERLOAD_PURE` should be used for pure virtual
The macro :func:`PYBIND11_OVERLOAD_PURE` should be used for pure virtual
functions, and :func:`PYBIND11_OVERLOAD` should be used for functions which have
functions, and :func:`PYBIND11_OVERLOAD` should be used for functions which have
a default implementation. The binding code also needs a few minor adaptations
a default implementation.
(highlighted):
There are also two alternate macros :func:`PYBIND11_OVERLOAD_PURE_NAME` and
:func:`PYBIND11_OVERLOAD_NAME` which take a string-valued name argument
after the *Name of the function* slot. This is useful when the C++ and Python
versions of the function have different names, e.g. ``operator()`` vs ``__call__``.
The binding code also needs a few minor adaptations (highlighted):
.. code-block:: cpp
.. code-block:: cpp
:emphasize-lines: 4,6,7
:emphasize-lines: 4,6,7
...
@@ -277,9 +283,8 @@ a default implementation. The binding code also needs a few minor adaptations
...
@@ -277,9 +283,8 @@ a default implementation. The binding code also needs a few minor adaptations
PYBIND11_PLUGIN(example) {
PYBIND11_PLUGIN(example) {
py::module m("example", "pybind11 example plugin");
py::module m("example", "pybind11 example plugin");
py::class_<
PyAnimal
> animal(m, "Animal");
py::class_<
Animal, std::unique_ptr<Animal>, PyAnimal /* <--- trampoline*/
> animal(m, "Animal");
animal
animal
.alias<Animal>()
.def(py::init<>())
.def(py::init<>())
.def("go", &Animal::go);
.def("go", &Animal::go);
...
@@ -291,10 +296,10 @@ a default implementation. The binding code also needs a few minor adaptations
...
@@ -291,10 +296,10 @@ a default implementation. The binding code also needs a few minor adaptations
return m.ptr();
return m.ptr();
}
}
Importantly,
the trampoline helper class is used as the template argument to
Importantly,
pybind11 is made aware of the trampoline trampoline helper class
:class:`class_`, and a call to :func:`class_::alias` informs the binding
by specifying it as the *third* template argument to :class:`class_`. The
generator that this is merely an alias for the underlying type ``Animal``.
second argument with the unique pointer is simply the default holder type used
Following this, we are able to define a constructor as usual.
by pybind11.
Following this, we are able to define a constructor as usual.
The Python session below shows how to override ``Animal::go`` and invoke it via
The Python session below shows how to override ``Animal::go`` and invoke it via
a virtual method call.
a virtual method call.
...
@@ -315,12 +320,12 @@ a virtual method call.
...
@@ -315,12 +320,12 @@ a virtual method call.
.. warning::
.. warning::
Both :func:`PYBIND11_OVERLOAD` and :func:`PYBIND11_OVERLOAD_PURE` are
The :func:`PYBIND11_OVERLOAD_*` calls are all just macros, which means that
macros, which means that they can get confused by commas in a template
they can get confused by commas in a template argument such as
argument such as ``PYBIND11_OVERLOAD(MyReturnValue<T1, T2>, myFunc)``. In
``PYBIND11_OVERLOAD(MyReturnValue<T1, T2>, myFunc)``. In this case, the
this case, the preprocessor assumes that the comma indicates the beginnning
preprocessor assumes that the comma indicates the beginnning of the next
of the next parameter. Use a ``typedef`` to bind the template to another
parameter. Use a ``typedef`` to bind the template to another name and use
name and use
it in the macro to avoid this problem.
it in the macro to avoid this problem.
.. seealso::
.. seealso::
...
@@ -363,9 +368,8 @@ be realized as follows (important changes highlighted):
...
@@ -363,9 +368,8 @@ be realized as follows (important changes highlighted):
PYBIND11_PLUGIN(example) {
PYBIND11_PLUGIN(example) {
py::module m("example", "pybind11 example plugin");
py::module m("example", "pybind11 example plugin");
py::class_<PyAnimal> animal(m, "Animal");
py::class_<
Animal, std::unique_ptr<Animal>,
PyAnimal> animal(m, "Animal");
animal
animal
.alias<Animal>()
.def(py::init<>())
.def(py::init<>())
.def("go", &Animal::go);
.def("go", &Animal::go);
...
...
docs/changelog.rst
View file @
9309b022
...
@@ -5,9 +5,11 @@ Changelog
...
@@ -5,9 +5,11 @@ Changelog
1.8 (Not yet released)
1.8 (Not yet released)
----------------------
----------------------
* Redesigned virtual call mechanism and user-facing syntax (breaking change!)
* Prevent implicit conversion of floating point values to integral types in
* Prevent implicit conversion of floating point values to integral types in
function arguments
function arguments
* Transparent conversion of sparse and dense Eigen data types
* Transparent conversion of sparse and dense Eigen data types
* ``std::vector<>`` type bindings analogous to Boost.Python's ``indexing_suite``
* Fixed incorrect default return value policy for functions returning a shared
* Fixed incorrect default return value policy for functions returning a shared
pointer
pointer
* Don't allow casting a ``None`` value into a C++ lvalue reference
* Don't allow casting a ``None`` value into a C++ lvalue reference
...
@@ -16,10 +18,19 @@ Changelog
...
@@ -16,10 +18,19 @@ Changelog
* Extended ``str`` type to also work with ``bytes`` instances
* Extended ``str`` type to also work with ``bytes`` instances
* Added ``[[noreturn]]`` attribute to ``pybind11_fail()`` to quench some
* Added ``[[noreturn]]`` attribute to ``pybind11_fail()`` to quench some
compiler warnings
compiler warnings
* List function arguments in exception text when the dispatch code cannot find
a matching overload
* Various minor ``iterator`` and ``make_iterator()`` improvements
* Various minor ``iterator`` and ``make_iterator()`` improvements
* Transparently support ``__bool__`` on Python 2.x and Python 3.x
* Fixed issue with destructor of unpickled object not being called
* Minor CMake build system improvements on Windows
* Minor CMake build system improvements on Windows
* Many ``mkdoc.py`` improvements (enumerations, template arguments, ``DOC()``
* Many ``mkdoc.py`` improvements (enumerations, template arguments, ``DOC()``
macro accepts more arguments)
macro accepts more arguments)
* New ``pybind11::args`` and ``pybind11::kwargs`` types to create functions which
take an arbitrary number of arguments and keyword arguments
* New syntax to call a Python function from C++ using ``*args`` and ``*kwargs``
* Added an ``ExtraFlags`` template argument to the NumPy ``array_t<>`` wrapper. This
can be used to disable an enforced cast that may lose precision
* Documentation improvements (pickling support, ``keep_alive``)
* Documentation improvements (pickling support, ``keep_alive``)
1.7 (April 30, 2016)
1.7 (April 30, 2016)
...
...
docs/conf.py
View file @
9309b022
...
@@ -56,9 +56,9 @@ author = 'Wenzel Jakob'
...
@@ -56,9 +56,9 @@ author = 'Wenzel Jakob'
# built documents.
# built documents.
#
#
# The short X.Y version.
# The short X.Y version.
version
=
'1.
0
'
version
=
'1.
8
'
# The full version, including alpha/beta/rc tags.
# The full version, including alpha/beta/rc tags.
release
=
'1.
0
'
release
=
'1.
8
'
# The language for content autogenerated by Sphinx. Refer to documentation
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
# for a list of supported languages.
...
...
docs/release.rst
View file @
9309b022
...
@@ -2,7 +2,8 @@ To release a new version of pybind11:
...
@@ -2,7 +2,8 @@ To release a new version of pybind11:
- Update the version number and push to pypi
- Update the version number and push to pypi
- Update ``pybind11/_version.py`` (set release version, remove 'dev')
- Update ``pybind11/_version.py`` (set release version, remove 'dev')
- Tag release date in ``doc/changelog.rst``.
- Update version in ``docs/conf.py``
- Tag release date in ``docs/changelog.rst``.
- ``git add`` and ``git commit``.
- ``git add`` and ``git commit``.
- ``git tag -a vX.Y -m 'vX.Y release'``.
- ``git tag -a vX.Y -m 'vX.Y release'``.
- ``git push``
- ``git push``
...
...
example/example11.cpp
View file @
9309b022
...
@@ -27,8 +27,8 @@ py::object call_kw_func(py::function f) {
...
@@ -27,8 +27,8 @@ py::object call_kw_func(py::function f) {
}
}
void
args_function
(
py
::
args
args
)
{
void
args_function
(
py
::
args
args
)
{
for
(
auto
item
:
args
)
for
(
size_t
it
=
0
;
it
<
args
.
size
();
++
it
)
std
::
cout
<<
"got argument: "
<<
item
<<
std
::
endl
;
std
::
cout
<<
"got argument: "
<<
py
::
object
(
args
[
it
])
<<
std
::
endl
;
}
}
void
args_kwargs_function
(
py
::
args
args
,
py
::
kwargs
kwargs
)
{
void
args_kwargs_function
(
py
::
args
args
,
py
::
kwargs
kwargs
)
{
...
...
example/example11.ref
View file @
9309b022
...
@@ -29,7 +29,7 @@ kw_func(x=5, y=10)
...
@@ -29,7 +29,7 @@ kw_func(x=5, y=10)
kw_func(x=5, y=10)
kw_func(x=5, y=10)
Caught expected exception: Incompatible function arguments. The following argument types are supported:
Caught expected exception: Incompatible function arguments. The following argument types are supported:
1. (x : int = 100L, y : int = 200L) -> NoneType
1. (x : int = 100L, y : int = 200L) -> NoneType
Invoked with:
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)
...
...
example/example12.cpp
View file @
9309b022
...
@@ -82,15 +82,11 @@ void runExample12Virtual(Example12 *ex) {
...
@@ -82,15 +82,11 @@ void runExample12Virtual(Example12 *ex) {
}
}
void
init_ex12
(
py
::
module
&
m
)
{
void
init_ex12
(
py
::
module
&
m
)
{
/* Important: use the wrapper type as a template
/* Important: indicate the trampoline class PyExample12 using the third
argument to class_<>, but use the original name
argument to py::class_. The second argument with the unique pointer
to denote the type */
is simply the default holder type used by pybind11. */
py
::
class_
<
PyExample12
>
(
m
,
"Example12"
)
py
::
class_
<
Example12
,
std
::
unique_ptr
<
Example12
>
,
PyExample12
>
(
m
,
"Example12"
)
/* Declare that 'PyExample12' is really an alias for the original type 'Example12' */
.
alias
<
Example12
>
()
.
def
(
py
::
init
<
int
>
())
.
def
(
py
::
init
<
int
>
())
/* Copy constructor (not needed in this case, but should generally be declared in this way) */
.
def
(
py
::
init
<
const
PyExample12
&>
())
/* Reference original class in function definitions */
/* Reference original class in function definitions */
.
def
(
"run"
,
&
Example12
::
run
)
.
def
(
"run"
,
&
Example12
::
run
)
.
def
(
"run_bool"
,
&
Example12
::
run_bool
)
.
def
(
"run_bool"
,
&
Example12
::
run_bool
)
...
...
example/example12.ref
View file @
9309b022
Constructing Example12..
Constructing Example12..
Original implementation of Example12::run(state=10, value=20)
Original implementation of Example12::run(state=10, value=20)
30
30
Caught expected exception: Tried to call pure virtual function "pure_virtual"
Caught expected exception: Tried to call pure virtual function "
Example12::
pure_virtual"
Constructing Example12..
Constructing Example12..
ExtendedExample12::run(20), calling parent..
ExtendedExample12::run(20), calling parent..
Original implementation of Example12::run(state=11, value=21)
Original implementation of Example12::run(state=11, value=21)
...
...
example/example14.ref
View file @
9309b022
...
@@ -11,7 +11,7 @@ Got void ptr : 0x7f9ba0f3c430
...
@@ -11,7 +11,7 @@ Got void ptr : 0x7f9ba0f3c430
Called Example1 destructor (0)
Called Example1 destructor (0)
Caught expected exception: Incompatible function arguments. The following argument types are supported:
Caught expected exception: Incompatible function arguments. The following argument types are supported:
1. (capsule) -> NoneType
1. (capsule) -> NoneType
Invoked with: [1, 2, 3]
None
None
Got null str : 0x0
Got null str : 0x0
<example.StringList object at 0x10d3277a0>
<example.StringList object at 0x10d3277a0>
...
...
example/example5.ref
View file @
9309b022
...
@@ -14,7 +14,7 @@ Polly is a parrot
...
@@ -14,7 +14,7 @@ Polly is a parrot
Molly is a dog
Molly is a dog
The following error is expected: Incompatible function arguments. The following argument types are supported:
The following error is expected: Incompatible function arguments. The following argument types are supported:
1. (example.Dog) -> NoneType
1. (example.Dog) -> NoneType
Invoked with: <Pet object at 0>
Callback function 1 called!
Callback function 1 called!
False
False
Callback function 2 called : Hello, x, True, 5
Callback function 2 called : Hello, x, True, 5
...
...
example/issues.cpp
View file @
9309b022
...
@@ -42,8 +42,7 @@ void init_issues(py::module &m) {
...
@@ -42,8 +42,7 @@ void init_issues(py::module &m) {
}
}
};
};
py
::
class_
<
DispatchIssue
>
base
(
m2
,
"DispatchIssue"
);
py
::
class_
<
Base
,
std
::
unique_ptr
<
Base
>
,
DispatchIssue
>
(
m2
,
"DispatchIssue"
)
base
.
alias
<
Base
>
()
.
def
(
py
::
init
<>
())
.
def
(
py
::
init
<>
())
.
def
(
"dispatch"
,
&
Base
::
dispatch
);
.
def
(
"dispatch"
,
&
Base
::
dispatch
);
...
@@ -108,4 +107,28 @@ void init_issues(py::module &m) {
...
@@ -108,4 +107,28 @@ void init_issues(py::module &m) {
// (no id): don't cast doubles to ints
// (no id): don't cast doubles to ints
m2
.
def
(
"expect_float"
,
[](
float
f
)
{
return
f
;
});
m2
.
def
(
"expect_float"
,
[](
float
f
)
{
return
f
;
});
m2
.
def
(
"expect_int"
,
[](
int
i
)
{
return
i
;
});
m2
.
def
(
"expect_int"
,
[](
int
i
)
{
return
i
;
});
// (no id): don't invoke Python dispatch code when instantiating C++
// classes that were not extended on the Python side
struct
A
{
virtual
~
A
()
{}
virtual
void
f
()
{
std
::
cout
<<
"A.f()"
<<
std
::
endl
;
}
};
struct
PyA
:
A
{
PyA
()
{
std
::
cout
<<
"PyA.PyA()"
<<
std
::
endl
;
}
void
f
()
override
{
std
::
cout
<<
"PyA.f()"
<<
std
::
endl
;
PYBIND11_OVERLOAD
(
void
,
A
,
f
);
}
};
auto
call_f
=
[](
A
*
a
)
{
a
->
f
();
};
pybind11
::
class_
<
A
,
std
::
unique_ptr
<
A
>
,
PyA
>
(
m2
,
"A"
)
.
def
(
py
::
init
<>
())
.
def
(
"f"
,
&
A
::
f
);
m2
.
def
(
"call_f"
,
call_f
);
}
}
example/issues.py
View file @
9309b022
...
@@ -9,6 +9,7 @@ from example.issues import Placeholder, return_vec_of_reference_wrapper
...
@@ -9,6 +9,7 @@ from example.issues import Placeholder, return_vec_of_reference_wrapper
from
example.issues
import
iterator_passthrough
from
example.issues
import
iterator_passthrough
from
example.issues
import
ElementList
,
ElementA
,
print_element
from
example.issues
import
ElementList
,
ElementA
,
print_element
from
example.issues
import
expect_float
,
expect_int
from
example.issues
import
expect_float
,
expect_int
from
example.issues
import
A
,
call_f
import
gc
import
gc
print_cchar
(
"const char *"
)
print_cchar
(
"const char *"
)
...
@@ -55,3 +56,19 @@ except Exception as e:
...
@@ -55,3 +56,19 @@ except Exception as e:
print
(
"Failed as expected: "
+
str
(
e
))
print
(
"Failed as expected: "
+
str
(
e
))
print
(
expect_float
(
12
))
print
(
expect_float
(
12
))
class
B
(
A
):
def
__init__
(
self
):
super
(
B
,
self
)
.
__init__
()
def
f
(
self
):
print
(
"In python f()"
)
print
(
"C++ version"
)
a
=
A
()
call_f
(
a
)
print
(
"Python version"
)
b
=
B
()
call_f
(
b
)
example/issues.ref
View file @
9309b022
const char *
const char *
c
c
Failed as expected: Tried to call pure virtual function "dispatch"
Failed as expected: Tried to call pure virtual function "
Base::
dispatch"
Yay..
Yay..
[Placeholder[1], Placeholder[2], Placeholder[3], Placeholder[4]]
[Placeholder[1], Placeholder[2], Placeholder[3], Placeholder[4]]
[3, 5, 7, 9, 11, 13, 15]
[3, 5, 7, 9, 11, 13, 15]
0==0, 1==1, 2==2, 3==3, 4==4, 5==5, 6==6, 7==7, 8==8, 9==9,
0==0, 1==1, 2==2, 3==3, 4==4, 5==5, 6==6, 7==7, 8==8, 9==9,
Failed as expected: Incompatible function arguments. The following argument types are supported:
Failed as expected: Incompatible function arguments. The following argument types are supported:
1. (example.issues.ElementA) -> NoneType
1. (example.issues.ElementA) -> NoneType
Invoked with: None
Failed as expected: Incompatible function arguments. The following argument types are supported:
Failed as expected: Incompatible function arguments. The following argument types are supported:
1. (int) -> int
1. (int) -> int
Invoked with: 5.2
12.0
12.0
C++ version
A.f()
Python version
PyA.PyA()
PyA.f()
In python f()
include/pybind11/attr.h
View file @
9309b022
...
@@ -65,6 +65,7 @@ enum op_type : int;
...
@@ -65,6 +65,7 @@ enum op_type : int;
struct
undefined_t
;
struct
undefined_t
;
template
<
op_id
id
,
op_type
ot
,
typename
L
=
undefined_t
,
typename
R
=
undefined_t
>
struct
op_
;
template
<
op_id
id
,
op_type
ot
,
typename
L
=
undefined_t
,
typename
R
=
undefined_t
>
struct
op_
;
template
<
typename
...
Args
>
struct
init
;
template
<
typename
...
Args
>
struct
init
;
template
<
typename
...
Args
>
struct
init_alias
;
inline
void
keep_alive_impl
(
int
Nurse
,
int
Patient
,
handle
args
,
handle
ret
);
inline
void
keep_alive_impl
(
int
Nurse
,
int
Patient
,
handle
args
,
handle
ret
);
/// Internal data structure which holds metadata about a keyword argument
/// Internal data structure which holds metadata about a keyword argument
...
...
include/pybind11/cast.h
View file @
9309b022
...
@@ -660,7 +660,7 @@ public:
...
@@ -660,7 +660,7 @@ public:
std
::
get
<
1
>
(
value
).
load
(
kwargs
,
convert
);
std
::
get
<
1
>
(
value
).
load
(
kwargs
,
convert
);
return
true
;
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
());
}
}
...
...
include/pybind11/eigen.h
View file @
9309b022
...
@@ -133,7 +133,7 @@ struct type_caster<Type, typename std::enable_if<is_eigen_dense<Type>::value>::t
...
@@ -133,7 +133,7 @@ struct type_caster<Type, typename std::enable_if<is_eigen_dense<Type>::value>::t
operator
Type
*
()
{
return
&
value
;
}
operator
Type
*
()
{
return
&
value
;
}
operator
Type
&
()
{
return
value
;
}
operator
Type
&
()
{
return
value
;
}
pr
ivate
:
pr
otected
:
template
<
typename
T
=
Type
,
typename
std
::
enable_if
<
T
::
RowsAtCompileTime
==
Eigen
::
Dynamic
,
int
>::
type
=
0
>
template
<
typename
T
=
Type
,
typename
std
::
enable_if
<
T
::
RowsAtCompileTime
==
Eigen
::
Dynamic
,
int
>::
type
=
0
>
static
PYBIND11_DESCR
rows
()
{
return
_
(
"m"
);
}
static
PYBIND11_DESCR
rows
()
{
return
_
(
"m"
);
}
template
<
typename
T
=
Type
,
typename
std
::
enable_if
<
T
::
RowsAtCompileTime
!=
Eigen
::
Dynamic
,
int
>::
type
=
0
>
template
<
typename
T
=
Type
,
typename
std
::
enable_if
<
T
::
RowsAtCompileTime
!=
Eigen
::
Dynamic
,
int
>::
type
=
0
>
...
@@ -143,7 +143,7 @@ private:
...
@@ -143,7 +143,7 @@ private:
template
<
typename
T
=
Type
,
typename
std
::
enable_if
<
T
::
ColsAtCompileTime
!=
Eigen
::
Dynamic
,
int
>::
type
=
0
>
template
<
typename
T
=
Type
,
typename
std
::
enable_if
<
T
::
ColsAtCompileTime
!=
Eigen
::
Dynamic
,
int
>::
type
=
0
>
static
PYBIND11_DESCR
cols
()
{
return
_
<
T
::
ColsAtCompileTime
>
();
}
static
PYBIND11_DESCR
cols
()
{
return
_
<
T
::
ColsAtCompileTime
>
();
}
pr
ivate
:
pr
otected
:
Type
value
;
Type
value
;
};
};
...
@@ -269,7 +269,7 @@ struct type_caster<Type, typename std::enable_if<is_eigen_sparse<Type>::value>::
...
@@ -269,7 +269,7 @@ struct type_caster<Type, typename std::enable_if<is_eigen_sparse<Type>::value>::
operator
Type
*
()
{
return
&
value
;
}
operator
Type
*
()
{
return
&
value
;
}
operator
Type
&
()
{
return
value
;
}
operator
Type
&
()
{
return
value
;
}
pr
ivate
:
pr
otected
:
Type
value
;
Type
value
;
};
};
...
...
include/pybind11/pybind11.h
View file @
9309b022
...
@@ -422,6 +422,14 @@ protected:
...
@@ -422,6 +422,14 @@ protected:
msg
+=
it2
->
signature
;
msg
+=
it2
->
signature
;
msg
+=
"
\n
"
;
msg
+=
"
\n
"
;
}
}
msg
+=
" Invoked with: "
;
tuple
args_
(
args
,
true
);
for
(
std
::
size_t
ti
=
0
;
ti
!=
args_
.
size
();
++
ti
)
{
msg
+=
static_cast
<
std
::
string
>
(
static_cast
<
object
>
(
args_
[
ti
]).
str
());
if
((
ti
+
1
)
!=
args_
.
size
()
)
msg
+=
", "
;
}
PyErr_SetString
(
PyExc_TypeError
,
msg
.
c_str
());
PyErr_SetString
(
PyExc_TypeError
,
msg
.
c_str
());
return
nullptr
;
return
nullptr
;
}
else
if
(
!
result
)
{
}
else
if
(
!
result
)
{
...
@@ -495,7 +503,7 @@ public:
...
@@ -495,7 +503,7 @@ public:
NAMESPACE_BEGIN
(
detail
)
NAMESPACE_BEGIN
(
detail
)
/// Generic support for creating new Python heap types
/// Generic support for creating new Python heap types
class
generic_type
:
public
object
{
class
generic_type
:
public
object
{
template
<
typename
type
,
typename
holder_type
>
friend
class
class_
;
template
<
typename
type
,
typename
holder_type
,
typename
type_alias
>
friend
class
class_
;
public
:
public
:
PYBIND11_OBJECT_DEFAULT
(
generic_type
,
object
,
PyType_Check
)
PYBIND11_OBJECT_DEFAULT
(
generic_type
,
object
,
PyType_Check
)
protected
:
protected
:
...
@@ -713,7 +721,7 @@ protected:
...
@@ -713,7 +721,7 @@ protected:
};
};
NAMESPACE_END
(
detail
)
NAMESPACE_END
(
detail
)
template
<
typename
type
,
typename
holder_type
=
std
::
unique_ptr
<
type
>>
template
<
typename
type
,
typename
holder_type
=
std
::
unique_ptr
<
type
>
,
typename
type_alias
=
type
>
class
class_
:
public
detail
::
generic_type
{
class
class_
:
public
detail
::
generic_type
{
public
:
public
:
typedef
detail
::
instance
<
type
,
holder_type
>
instance_type
;
typedef
detail
::
instance
<
type
,
holder_type
>
instance_type
;
...
@@ -735,6 +743,11 @@ public:
...
@@ -735,6 +743,11 @@ public:
detail
::
process_attributes
<
Extra
...
>::
init
(
extra
...,
&
record
);
detail
::
process_attributes
<
Extra
...
>::
init
(
extra
...,
&
record
);
detail
::
generic_type
::
initialize
(
&
record
);
detail
::
generic_type
::
initialize
(
&
record
);
if
(
!
std
::
is_same
<
type
,
type_alias
>::
value
)
{
auto
&
instances
=
pybind11
::
detail
::
get_internals
().
registered_types_cpp
;
instances
[
std
::
type_index
(
typeid
(
type_alias
))]
=
instances
[
std
::
type_index
(
typeid
(
type
))];
}
}
}
template
<
typename
Func
,
typename
...
Extra
>
template
<
typename
Func
,
typename
...
Extra
>
...
@@ -772,6 +785,12 @@ public:
...
@@ -772,6 +785,12 @@ public:
return
*
this
;
return
*
this
;
}
}
template
<
typename
...
Args
,
typename
...
Extra
>
class_
&
def
(
const
detail
::
init_alias
<
Args
...
>
&
init
,
const
Extra
&
...
extra
)
{
init
.
template
execute
<
type
>
(
*
this
,
extra
...);
return
*
this
;
}
template
<
typename
Func
>
class_
&
def_buffer
(
Func
&&
func
)
{
template
<
typename
Func
>
class_
&
def_buffer
(
Func
&&
func
)
{
struct
capture
{
Func
func
;
};
struct
capture
{
Func
func
;
};
capture
*
ptr
=
new
capture
{
std
::
forward
<
Func
>
(
func
)
};
capture
*
ptr
=
new
capture
{
std
::
forward
<
Func
>
(
func
)
};
...
@@ -848,11 +867,6 @@ public:
...
@@ -848,11 +867,6 @@ public:
return
*
this
;
return
*
this
;
}
}
template
<
typename
target
>
class_
alias
()
{
auto
&
instances
=
pybind11
::
detail
::
get_internals
().
registered_types_cpp
;
instances
[
std
::
type_index
(
typeid
(
target
))]
=
instances
[
std
::
type_index
(
typeid
(
type
))];
return
*
this
;
}
private
:
private
:
/// Initialize holder object, variant 1: object derives from enable_shared_from_this
/// Initialize holder object, variant 1: object derives from enable_shared_from_this
template
<
typename
T
>
template
<
typename
T
>
...
@@ -951,9 +965,31 @@ private:
...
@@ -951,9 +965,31 @@ private:
NAMESPACE_BEGIN
(
detail
)
NAMESPACE_BEGIN
(
detail
)
template
<
typename
...
Args
>
struct
init
{
template
<
typename
...
Args
>
struct
init
{
template
<
typename
Base
,
typename
Holder
,
typename
...
Extra
>
void
execute
(
pybind11
::
class_
<
Base
,
Holder
>
&
class_
,
const
Extra
&
...
extra
)
const
{
template
<
typename
Base
,
typename
Holder
,
typename
Alias
,
typename
...
Extra
,
typename
std
::
enable_if
<
std
::
is_same
<
Base
,
Alias
>::
value
,
int
>::
type
=
0
>
void
execute
(
pybind11
::
class_
<
Base
,
Holder
,
Alias
>
&
class_
,
const
Extra
&
...
extra
)
const
{
/// Function which calls a specific C++ in-place constructor
/// Function which calls a specific C++ in-place constructor
class_
.
def
(
"__init__"
,
[](
Base
*
instance
,
Args
...
args
)
{
new
(
instance
)
Base
(
args
...);
},
extra
...);
class_
.
def
(
"__init__"
,
[](
Base
*
self_
,
Args
...
args
)
{
new
(
self_
)
Base
(
args
...);
},
extra
...);
}
template
<
typename
Base
,
typename
Holder
,
typename
Alias
,
typename
...
Extra
,
typename
std
::
enable_if
<!
std
::
is_same
<
Base
,
Alias
>::
value
&&
std
::
is_constructible
<
Base
,
Args
...
>::
value
,
int
>::
type
=
0
>
void
execute
(
pybind11
::
class_
<
Base
,
Holder
,
Alias
>
&
class_
,
const
Extra
&
...
extra
)
const
{
handle
cl_type
=
class_
;
class_
.
def
(
"__init__"
,
[
cl_type
](
handle
self_
,
Args
...
args
)
{
if
(
self_
.
get_type
()
==
cl_type
)
new
(
self_
.
cast
<
Base
*>
())
Base
(
args
...);
else
new
(
self_
.
cast
<
Alias
*>
())
Alias
(
args
...);
},
extra
...);
}
template
<
typename
Base
,
typename
Holder
,
typename
Alias
,
typename
...
Extra
,
typename
std
::
enable_if
<!
std
::
is_same
<
Base
,
Alias
>::
value
&&
!
std
::
is_constructible
<
Base
,
Args
...
>::
value
,
int
>::
type
=
0
>
void
execute
(
pybind11
::
class_
<
Base
,
Holder
,
Alias
>
&
class_
,
const
Extra
&
...
extra
)
const
{
class_
.
def
(
"__init__"
,
[](
Alias
*
self
,
Args
...
args
)
{
new
(
self
)
Alias
(
args
...);
},
extra
...);
}
}
};
};
...
@@ -1038,6 +1074,11 @@ template <typename InputType, typename OutputType> void implicitly_convertible()
...
@@ -1038,6 +1074,11 @@ template <typename InputType, typename OutputType> void implicitly_convertible()
* can be handy to prevent cases where callbacks issued from an external
* can be handy to prevent cases where callbacks issued from an external
* thread would otherwise constantly construct and destroy thread state data
* thread would otherwise constantly construct and destroy thread state data
* structures.
* structures.
*
* See the Python bindings of NanoGUI (http://github.com/wjakob/nanogui) for an
* example which uses features 2 and 3 to migrate the Python thread of
* execution to another thread (to run the event loop on the original thread,
* in this case).
*/
*/
class
gil_scoped_acquire
{
class
gil_scoped_acquire
{
...
@@ -1176,19 +1217,25 @@ inline function get_overload(const void *this_ptr, const char *name) {
...
@@ -1176,19 +1217,25 @@ inline function get_overload(const void *this_ptr, const char *name) {
return
overload
;
return
overload
;
}
}
#define PYBIND11_OVERLOAD_INT(ret_type,
class_name,
name, ...) { \
#define PYBIND11_OVERLOAD_INT(ret_type, name, ...) { \
pybind11::gil_scoped_acquire gil; \
pybind11::gil_scoped_acquire gil; \
pybind11::function overload = pybind11::get_overload(this,
#
name); \
pybind11::function overload = pybind11::get_overload(this, name); \
if (overload) \
if (overload) \
return overload(__VA_ARGS__).template cast<ret_type>(); }
return overload(__VA_ARGS__).template cast<ret_type>(); }
#define PYBIND11_OVERLOAD(ret_type, class_name, name, ...) \
#define PYBIND11_OVERLOAD_NAME(ret_type, cname, name, fn, ...) \
PYBIND11_OVERLOAD_INT(ret_type, class_name, name, __VA_ARGS__) \
PYBIND11_OVERLOAD_INT(ret_type, name, __VA_ARGS__) \
return class_name::name(__VA_ARGS__)
return cname::fn(__VA_ARGS__)
#define PYBIND11_OVERLOAD_PURE_NAME(ret_type, cname, name, fn, ...) \
PYBIND11_OVERLOAD_INT(ret_type, name, __VA_ARGS__) \
pybind11::pybind11_fail("Tried to call pure virtual function \"" #cname "::" name "\"");
#define PYBIND11_OVERLOAD(ret_type, cname, fn, ...) \
PYBIND11_OVERLOAD_NAME(ret_type, cname, #fn, fn, __VA_ARGS__)
#define PYBIND11_OVERLOAD_PURE(ret_type, class_name, name, ...) \
#define PYBIND11_OVERLOAD_PURE(ret_type, cname, fn, ...) \
PYBIND11_OVERLOAD_INT(ret_type, class_name, name, __VA_ARGS__) \
PYBIND11_OVERLOAD_PURE_NAME(ret_type, cname, #fn, fn, __VA_ARGS__)
pybind11::pybind11_fail("Tried to call pure virtual function \"" #name "\"");
NAMESPACE_END
(
pybind11
)
NAMESPACE_END
(
pybind11
)
...
...
include/pybind11/pytypes.h
View file @
9309b022
...
@@ -323,10 +323,10 @@ public:
...
@@ -323,10 +323,10 @@ public:
PYBIND11_OBJECT_DEFAULT
(
iterable
,
object
,
detail
::
PyIterable_Check
)
PYBIND11_OBJECT_DEFAULT
(
iterable
,
object
,
detail
::
PyIterable_Check
)
};
};
inline
detail
::
accessor
handle
::
operator
[](
handle
key
)
const
{
return
detail
::
accessor
(
ptr
(),
key
.
ptr
()
,
false
);
}
inline
detail
::
accessor
handle
::
operator
[](
handle
key
)
const
{
return
detail
::
accessor
(
*
this
,
key
,
false
);
}
inline
detail
::
accessor
handle
::
operator
[](
const
char
*
key
)
const
{
return
detail
::
accessor
(
ptr
()
,
key
,
false
);
}
inline
detail
::
accessor
handle
::
operator
[](
const
char
*
key
)
const
{
return
detail
::
accessor
(
*
this
,
key
,
false
);
}
inline
detail
::
accessor
handle
::
attr
(
handle
key
)
const
{
return
detail
::
accessor
(
ptr
(),
key
.
ptr
()
,
true
);
}
inline
detail
::
accessor
handle
::
attr
(
handle
key
)
const
{
return
detail
::
accessor
(
*
this
,
key
,
true
);
}
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
(
*
this
,
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_proxy
handle
::
operator
*
()
const
{
return
detail
::
args_proxy
(
*
this
);
}
inline
detail
::
args_proxy
handle
::
operator
*
()
const
{
return
detail
::
args_proxy
(
*
this
);
}
...
@@ -491,7 +491,7 @@ public:
...
@@ -491,7 +491,7 @@ public:
if
(
!
m_ptr
)
pybind11_fail
(
"Could not allocate tuple object!"
);
if
(
!
m_ptr
)
pybind11_fail
(
"Could not allocate tuple object!"
);
}
}
size_t
size
()
const
{
return
(
size_t
)
PyTuple_Size
(
m_ptr
);
}
size_t
size
()
const
{
return
(
size_t
)
PyTuple_Size
(
m_ptr
);
}
detail
::
tuple_accessor
operator
[](
size_t
index
)
const
{
return
detail
::
tuple_accessor
(
ptr
()
,
index
);
}
detail
::
tuple_accessor
operator
[](
size_t
index
)
const
{
return
detail
::
tuple_accessor
(
*
this
,
index
);
}
};
};
class
dict
:
public
object
{
class
dict
:
public
object
{
...
@@ -501,7 +501,7 @@ public:
...
@@ -501,7 +501,7 @@ public:
if
(
!
m_ptr
)
pybind11_fail
(
"Could not allocate dict object!"
);
if
(
!
m_ptr
)
pybind11_fail
(
"Could not allocate dict object!"
);
}
}
size_t
size
()
const
{
return
(
size_t
)
PyDict_Size
(
m_ptr
);
}
size_t
size
()
const
{
return
(
size_t
)
PyDict_Size
(
m_ptr
);
}
detail
::
dict_iterator
begin
()
const
{
return
(
++
detail
::
dict_iterator
(
ptr
()
,
0
));
}
detail
::
dict_iterator
begin
()
const
{
return
(
++
detail
::
dict_iterator
(
*
this
,
0
));
}
detail
::
dict_iterator
end
()
const
{
return
detail
::
dict_iterator
();
}
detail
::
dict_iterator
end
()
const
{
return
detail
::
dict_iterator
();
}
void
clear
()
const
{
PyDict_Clear
(
ptr
());
}
void
clear
()
const
{
PyDict_Clear
(
ptr
());
}
};
};
...
@@ -517,7 +517,7 @@ public:
...
@@ -517,7 +517,7 @@ 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
args
:
public
tuple
{
PYBIND11_OBJECT_DEFAULT
(
args
,
tuple
,
PyTuple
_Check
)
};
class
kwargs
:
public
dict
{
PYBIND11_OBJECT_DEFAULT
(
kwargs
,
dict
,
PyDict_Check
)
};
class
kwargs
:
public
dict
{
PYBIND11_OBJECT_DEFAULT
(
kwargs
,
dict
,
PyDict_Check
)
};
class
set
:
public
object
{
class
set
:
public
object
{
...
...
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