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
678d787c
Commit
678d787c
authored
Jan 17, 2016
by
Wenzel Jakob
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
do more work with classes from pytypes.h (especially for STL container casting)
parent
d561cb01
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
128 additions
and
105 deletions
+128
-105
README.md
+7
-7
docs/intro.rst
+7
-7
example/example4.ref
+1
-1
example/run_test.py
+2
-0
include/pybind11/common.h
+5
-2
include/pybind11/pybind11.h
+18
-21
include/pybind11/pytypes.h
+50
-26
include/pybind11/stl.h
+28
-32
include/pybind11/typeid.h
+2
-1
setup.py
+8
-8
No files found.
README.md
View file @
678d787c
...
@@ -22,13 +22,13 @@ C++11-compatible compilers are widely available, this heavy machinery has
...
@@ -22,13 +22,13 @@ C++11-compatible compilers are widely available, this heavy machinery has
become an excessively large and unnecessary dependency.
become an excessively large and unnecessary dependency.
Think of this library as a tiny self-contained version of Boost.Python with
Think of this library as a tiny self-contained version of Boost.Python with
everything stripped away that isn't relevant for binding generation.
The core
everything stripped away that isn't relevant for binding generation.
Without
header files only require ~2.5K lines of code and depend on Python (2.7 or 3.x)
comments, the core header files only require ~2.5K lines of code and depend on
and the C++ standard library. This compact implementation was possible thanks
Python (2.7 or 3.x) and the C++ standard library. This compact implementation
to some of the new C++11 language features (specifically: tuples, lambda
was possible thanks to some of the new C++11 language features (specifically:
functions and variadic templates). Since its creation, this library has grown
tuples, lambda functions and variadic templates). Since its creation, this
beyond Boost.Python in many ways, leading to dramatically simpler binding code
library has grown beyond Boost.Python in many ways, leading to dramatically
in many common situations.
simpler binding code
in many common situations.
Tutorial and reference documentation is provided at
Tutorial and reference documentation is provided at
[
http://pybind11.readthedocs.org/en/latest
](
http://pybind11.readthedocs.org/en/latest
)
.
[
http://pybind11.readthedocs.org/en/latest
](
http://pybind11.readthedocs.org/en/latest
)
.
...
...
docs/intro.rst
View file @
678d787c
...
@@ -19,13 +19,13 @@ C++11-compatible compilers are widely available, this heavy machinery has
...
@@ -19,13 +19,13 @@ C++11-compatible compilers are widely available, this heavy machinery has
become an excessively large and unnecessary dependency.
become an excessively large and unnecessary dependency.
Think of this library as a tiny self-contained version of Boost.Python with
Think of this library as a tiny self-contained version of Boost.Python with
everything stripped away that isn't relevant for binding generation.
The core
everything stripped away that isn't relevant for binding generation.
Without
header files only require ~2.5K lines of code and depend on Python (2.7 or 3.x)
comments, the core header files only require ~2.5K lines of code and depend on
and the C++ standard library. This compact implementation was possible thanks
Python (2.7 or 3.x) and the C++ standard library. This compact implementation
to some of the new C++11 language features (specifically: tuples, lambda
was possible thanks to some of the new C++11 language features (specifically:
functions and variadic templates). Since its creation, this library has grown
tuples, lambda functions and variadic templates). Since its creation, this
beyond Boost.Python in many ways, leading to dramatically simpler binding code
library has grown beyond Boost.Python in many ways, leading to dramatically
in many common situations.
simpler binding code
in many common situations.
Core features
Core features
*************
*************
...
...
example/example4.ref
View file @
678d787c
...
@@ -10,7 +10,7 @@ test_function(enum=1)
...
@@ -10,7 +10,7 @@ test_function(enum=1)
None
None
test_function(enum=2)
test_function(enum=2)
None
None
<class '
Example4
.EMode'>
<class '
example
.EMode'>
EMode.EFirstMode
EMode.EFirstMode
EMode.EFirstMode
EMode.EFirstMode
Example4::test_function(enum=1)
Example4::test_function(enum=1)
...
...
example/run_test.py
View file @
678d787c
...
@@ -22,6 +22,8 @@ def sanitize(lines):
...
@@ -22,6 +22,8 @@ def sanitize(lines):
line
=
line
.
replace
(
'__builtin__'
,
'builtins'
)
line
=
line
.
replace
(
'__builtin__'
,
'builtins'
)
line
=
line
.
replace
(
'example.'
,
''
)
line
=
line
.
replace
(
'example.'
,
''
)
line
=
line
.
replace
(
'unicode'
,
'str'
)
line
=
line
.
replace
(
'unicode'
,
'str'
)
line
=
line
.
replace
(
'Example4.EMode'
,
'EMode'
)
line
=
line
.
replace
(
'example.EMode'
,
'EMode'
)
line
=
line
.
replace
(
'method of builtins.PyCapsule instance'
,
''
)
line
=
line
.
replace
(
'method of builtins.PyCapsule instance'
,
''
)
line
=
line
.
strip
()
line
=
line
.
strip
()
if
sys
.
platform
==
'win32'
:
if
sys
.
platform
==
'win32'
:
...
...
include/pybind11/common.h
View file @
678d787c
...
@@ -225,8 +225,8 @@ struct argument_entry {
...
@@ -225,8 +225,8 @@ struct argument_entry {
/// Internal data struture used to track registered instances and types
/// Internal data struture used to track registered instances and types
struct
internals
{
struct
internals
{
std
::
unordered_map
<
const
void
*
,
void
*>
registered_types_cpp
;
// std::type_info* -> type_info
std
::
unordered_map
<
const
void
*
,
void
*>
registered_types_cpp
;
// std::type_info* -> type_info
std
::
unordered_map
<
const
void
*
,
void
*>
registered_types_py
;
// PyTypeObject* -> type_info
std
::
unordered_map
<
const
void
*
,
void
*>
registered_types_py
;
// PyTypeObject* -> type_info
std
::
unordered_map
<
const
void
*
,
void
*>
registered_instances
;
// void * -> PyObject*
std
::
unordered_map
<
const
void
*
,
void
*>
registered_instances
;
// void * -> PyObject*
std
::
unordered_set
<
std
::
pair
<
const
PyObject
*
,
const
char
*>
,
overload_hash
>
inactive_overload_cache
;
std
::
unordered_set
<
std
::
pair
<
const
PyObject
*
,
const
char
*>
,
overload_hash
>
inactive_overload_cache
;
};
};
...
@@ -271,4 +271,7 @@ struct error_already_set : public std::runtime_error { public: error_already_set
...
@@ -271,4 +271,7 @@ struct error_already_set : public std::runtime_error { public: error_already_set
/// Thrown when pybind11::cast or handle::call fail due to a type casting error
/// Thrown when pybind11::cast or handle::call fail due to a type casting error
struct
cast_error
:
public
std
::
runtime_error
{
public
:
cast_error
(
const
std
::
string
&
w
=
""
)
:
std
::
runtime_error
(
w
)
{}
};
struct
cast_error
:
public
std
::
runtime_error
{
public
:
cast_error
(
const
std
::
string
&
w
=
""
)
:
std
::
runtime_error
(
w
)
{}
};
PYBIND11_NOINLINE
inline
void
pybind11_fail
(
const
char
*
reason
)
{
throw
std
::
runtime_error
(
reason
);
}
PYBIND11_NOINLINE
inline
void
pybind11_fail
(
const
std
::
string
&
reason
)
{
throw
std
::
runtime_error
(
reason
);
}
NAMESPACE_END
(
pybind11
)
NAMESPACE_END
(
pybind11
)
include/pybind11/pybind11.h
View file @
678d787c
...
@@ -24,7 +24,6 @@
...
@@ -24,7 +24,6 @@
#endif
#endif
#include "cast.h"
#include "cast.h"
#include <iostream>
NAMESPACE_BEGIN
(
pybind11
)
NAMESPACE_BEGIN
(
pybind11
)
...
@@ -196,9 +195,9 @@ protected:
...
@@ -196,9 +195,9 @@ protected:
a
.
value
,
return_value_policy
::
automatic
,
nullptr
);
a
.
value
,
return_value_policy
::
automatic
,
nullptr
);
if
(
obj
==
nullptr
)
if
(
obj
==
nullptr
)
throw
std
::
runtime_error
(
"arg(): could not convert default keyword "
pybind11_fail
(
"arg(): could not convert default keyword "
"argument into a Python object (type not "
"argument into a Python object (type not "
"registered yet?)"
);
"registered yet?)"
);
entry
->
args
.
emplace_back
(
a
.
name
,
a
.
descr
,
obj
);
entry
->
args
.
emplace_back
(
a
.
name
,
a
.
descr
,
obj
);
}
}
...
@@ -490,7 +489,7 @@ protected:
...
@@ -490,7 +489,7 @@ protected:
}
else
if
(
c
==
'%'
)
{
}
else
if
(
c
==
'%'
)
{
const
std
::
type_info
*
t
=
types
[
type_index
++
];
const
std
::
type_info
*
t
=
types
[
type_index
++
];
if
(
!
t
)
if
(
!
t
)
throw
std
::
runtime_error
(
"Internal error while parsing type signature (1)"
);
pybind11_fail
(
"Internal error while parsing type signature (1)"
);
auto
it
=
registered_types
.
find
(
t
);
auto
it
=
registered_types
.
find
(
t
);
if
(
it
!=
registered_types
.
end
())
{
if
(
it
!=
registered_types
.
end
())
{
signature
+=
((
const
detail
::
type_info
*
)
it
->
second
)
->
type
->
tp_name
;
signature
+=
((
const
detail
::
type_info
*
)
it
->
second
)
->
type
->
tp_name
;
...
@@ -504,7 +503,7 @@ protected:
...
@@ -504,7 +503,7 @@ protected:
}
}
}
}
if
(
type_depth
!=
0
||
types
[
type_index
]
!=
nullptr
)
if
(
type_depth
!=
0
||
types
[
type_index
]
!=
nullptr
)
throw
std
::
runtime_error
(
"Internal error while parsing type signature (2)"
);
pybind11_fail
(
"Internal error while parsing type signature (2)"
);
#if !defined(PYBIND11_CPP14)
#if !defined(PYBIND11_CPP14)
delete
[]
types
;
delete
[]
types
;
...
@@ -519,7 +518,7 @@ protected:
...
@@ -519,7 +518,7 @@ protected:
#endif
#endif
if
(
!
m_entry
->
args
.
empty
()
&&
(
int
)
m_entry
->
args
.
size
()
!=
args
)
if
(
!
m_entry
->
args
.
empty
()
&&
(
int
)
m_entry
->
args
.
size
()
!=
args
)
throw
std
::
runtime_error
(
pybind11_fail
(
"cpp_function(): function
\"
"
+
std
::
string
(
m_entry
->
name
)
+
"
\"
takes "
+
"cpp_function(): function
\"
"
+
std
::
string
(
m_entry
->
name
)
+
"
\"
takes "
+
std
::
to_string
(
args
)
+
" arguments, but "
+
std
::
to_string
(
m_entry
->
args
.
size
())
+
std
::
to_string
(
args
)
+
" arguments, but "
+
std
::
to_string
(
m_entry
->
args
.
size
())
+
" pybind11::arg entries were specified!"
);
" pybind11::arg entries were specified!"
);
...
@@ -555,7 +554,7 @@ protected:
...
@@ -555,7 +554,7 @@ protected:
});
});
m_ptr
=
PyCFunction_New
(
m_entry
->
def
,
entry_capsule
.
ptr
());
m_ptr
=
PyCFunction_New
(
m_entry
->
def
,
entry_capsule
.
ptr
());
if
(
!
m_ptr
)
if
(
!
m_ptr
)
throw
std
::
runtime_error
(
"cpp_function::cpp_function(): Could not allocate function object"
);
pybind11_fail
(
"cpp_function::cpp_function(): Could not allocate function object"
);
}
else
{
}
else
{
/* Append at the end of the overload chain */
/* Append at the end of the overload chain */
m_ptr
=
m_entry
->
sibling
;
m_ptr
=
m_entry
->
sibling
;
...
@@ -597,7 +596,7 @@ protected:
...
@@ -597,7 +596,7 @@ protected:
m_ptr
=
PyMethod_New
(
m_ptr
,
nullptr
,
entry
->
class_
);
m_ptr
=
PyMethod_New
(
m_ptr
,
nullptr
,
entry
->
class_
);
#endif
#endif
if
(
!
m_ptr
)
if
(
!
m_ptr
)
throw
std
::
runtime_error
(
"cpp_function::cpp_function(): Could not allocate instance method object"
);
pybind11_fail
(
"cpp_function::cpp_function(): Could not allocate instance method object"
);
Py_DECREF
(
func
);
Py_DECREF
(
func
);
}
}
}
}
...
@@ -621,7 +620,7 @@ public:
...
@@ -621,7 +620,7 @@ public:
m_ptr
=
Py_InitModule3
(
name
,
nullptr
,
doc
);
m_ptr
=
Py_InitModule3
(
name
,
nullptr
,
doc
);
#endif
#endif
if
(
m_ptr
==
nullptr
)
if
(
m_ptr
==
nullptr
)
throw
std
::
runtime_error
(
"Internal error in module::module()"
);
pybind11_fail
(
"Internal error in module::module()"
);
inc_ref
();
inc_ref
();
}
}
...
@@ -647,7 +646,7 @@ public:
...
@@ -647,7 +646,7 @@ public:
static
module
import
(
const
char
*
name
)
{
static
module
import
(
const
char
*
name
)
{
PyObject
*
obj
=
PyImport_ImportModule
(
name
);
PyObject
*
obj
=
PyImport_ImportModule
(
name
);
if
(
!
obj
)
if
(
!
obj
)
throw
std
::
runtime_error
(
"Module
\"
"
+
std
::
string
(
name
)
+
"
\"
not found!"
);
pybind11_fail
(
"Module
\"
"
+
std
::
string
(
name
)
+
"
\"
not found!"
);
return
module
(
obj
,
false
);
return
module
(
obj
,
false
);
}
}
};
};
...
@@ -668,7 +667,7 @@ public:
...
@@ -668,7 +667,7 @@ public:
auto
type
=
(
PyHeapTypeObject
*
)
type_holder
.
ptr
();
auto
type
=
(
PyHeapTypeObject
*
)
type_holder
.
ptr
();
if
(
!
type_holder
||
!
name
)
if
(
!
type_holder
||
!
name
)
throw
std
::
runtime_error
(
"generic_type: unable to create type object!"
);
pybind11_fail
(
"generic_type: unable to create type object!"
);
/* Register supplemental type information in C++ dict */
/* Register supplemental type information in C++ dict */
auto
&
internals
=
get_internals
();
auto
&
internals
=
get_internals
();
...
@@ -732,7 +731,7 @@ public:
...
@@ -732,7 +731,7 @@ public:
}
}
if
(
PyType_Ready
(
&
type
->
ht_type
)
<
0
)
if
(
PyType_Ready
(
&
type
->
ht_type
)
<
0
)
throw
std
::
runtime_error
(
"generic_type: PyType_Ready failed!"
);
pybind11_fail
(
"generic_type: PyType_Ready failed!"
);
m_ptr
=
type_holder
.
ptr
();
m_ptr
=
type_holder
.
ptr
();
...
@@ -756,7 +755,7 @@ protected:
...
@@ -756,7 +755,7 @@ protected:
object
type_holder
(
PyType_Type
.
tp_alloc
(
&
PyType_Type
,
0
),
false
);
object
type_holder
(
PyType_Type
.
tp_alloc
(
&
PyType_Type
,
0
),
false
);
object
name
(
PYBIND11_FROM_STRING
(
name_
.
c_str
()),
false
);
object
name
(
PYBIND11_FROM_STRING
(
name_
.
c_str
()),
false
);
if
(
!
type_holder
||
!
name
)
if
(
!
type_holder
||
!
name
)
throw
std
::
runtime_error
(
"generic_type::metaclass(): unable to create type object!"
);
pybind11_fail
(
"generic_type::metaclass(): unable to create type object!"
);
auto
type
=
(
PyHeapTypeObject
*
)
type_holder
.
ptr
();
auto
type
=
(
PyHeapTypeObject
*
)
type_holder
.
ptr
();
type
->
ht_name
=
name
.
release
();
type
->
ht_name
=
name
.
release
();
...
@@ -767,7 +766,7 @@ protected:
...
@@ -767,7 +766,7 @@ protected:
~
Py_TPFLAGS_HAVE_GC
;
~
Py_TPFLAGS_HAVE_GC
;
if
(
PyType_Ready
(
&
type
->
ht_type
)
<
0
)
if
(
PyType_Ready
(
&
type
->
ht_type
)
<
0
)
throw
std
::
runtime_error
(
"generic_type::metaclass(): PyType_Ready failed!"
);
pybind11_fail
(
"generic_type::metaclass(): PyType_Ready failed!"
);
ob_type
=
(
PyTypeObject
*
)
type_holder
.
release
();
ob_type
=
(
PyTypeObject
*
)
type_holder
.
release
();
}
}
...
@@ -798,7 +797,7 @@ protected:
...
@@ -798,7 +797,7 @@ protected:
auto
&
registered_instances
=
detail
::
get_internals
().
registered_instances
;
auto
&
registered_instances
=
detail
::
get_internals
().
registered_instances
;
auto
it
=
registered_instances
.
find
(
self
->
value
);
auto
it
=
registered_instances
.
find
(
self
->
value
);
if
(
it
==
registered_instances
.
end
())
if
(
it
==
registered_instances
.
end
())
throw
std
::
runtime_error
(
"generic_type::dealloc(): Tried to deallocate unregistered instance!"
);
pybind11_fail
(
"generic_type::dealloc(): Tried to deallocate unregistered instance!"
);
registered_instances
.
erase
(
it
);
registered_instances
.
erase
(
it
);
}
}
Py_XDECREF
(
self
->
parent
);
Py_XDECREF
(
self
->
parent
);
...
@@ -1096,14 +1095,12 @@ PYBIND11_NOINLINE inline void keep_alive_impl(int Nurse, int Patient, PyObject *
...
@@ -1096,14 +1095,12 @@ PYBIND11_NOINLINE inline void keep_alive_impl(int Nurse, int Patient, PyObject *
handle
patient
(
Patient
>
0
?
PyTuple_GetItem
(
arg
,
Patient
-
1
)
:
ret
);
handle
patient
(
Patient
>
0
?
PyTuple_GetItem
(
arg
,
Patient
-
1
)
:
ret
);
if
(
!
nurse
||
!
patient
)
if
(
!
nurse
||
!
patient
)
throw
std
::
runtime_error
(
"Could not activate keep_alive!"
);
pybind11_fail
(
"Could not activate keep_alive!"
);
cpp_function
disable_lifesupport
(
cpp_function
disable_lifesupport
(
[
patient
](
handle
weakref
)
{
patient
.
dec_ref
();
weakref
.
dec_ref
();
});
[
patient
](
handle
weakref
)
{
patient
.
dec_ref
();
weakref
.
dec_ref
();
});
weakref
wr
(
nurse
,
disable_lifesupport
);
weakref
wr
(
nurse
,
disable_lifesupport
);
if
(
!
wr
)
throw
std
::
runtime_error
(
"Could not allocate weak reference!"
);
patient
.
inc_ref
();
/* reference patient and leak the weak reference */
patient
.
inc_ref
();
/* reference patient and leak the weak reference */
(
void
)
wr
.
release
();
(
void
)
wr
.
release
();
...
@@ -1138,7 +1135,7 @@ template <typename InputType, typename OutputType> void implicitly_convertible()
...
@@ -1138,7 +1135,7 @@ template <typename InputType, typename OutputType> void implicitly_convertible()
auto
&
registered_types
=
detail
::
get_internals
().
registered_types_cpp
;
auto
&
registered_types
=
detail
::
get_internals
().
registered_types_cpp
;
auto
it
=
registered_types
.
find
(
&
typeid
(
OutputType
));
auto
it
=
registered_types
.
find
(
&
typeid
(
OutputType
));
if
(
it
==
registered_types
.
end
())
if
(
it
==
registered_types
.
end
())
throw
std
::
runtime_error
(
"implicitly_convertible: Unable to find type "
+
type_id
<
OutputType
>
());
pybind11_fail
(
"implicitly_convertible: Unable to find type "
+
type_id
<
OutputType
>
());
((
detail
::
type_info
*
)
it
->
second
)
->
implicit_conversions
.
push_back
(
implicit_caster
);
((
detail
::
type_info
*
)
it
->
second
)
->
implicit_conversions
.
push_back
(
implicit_caster
);
}
}
...
@@ -1196,7 +1193,7 @@ inline function get_overload(const void *this_ptr, const char *name) {
...
@@ -1196,7 +1193,7 @@ inline function get_overload(const void *this_ptr, const char *name) {
#define PYBIND11_OVERLOAD_PURE(ret_type, class_name, name, ...) \
#define PYBIND11_OVERLOAD_PURE(ret_type, class_name, name, ...) \
PYBIND11_OVERLOAD_INT(ret_type, class_name, name, __VA_ARGS__) \
PYBIND11_OVERLOAD_INT(ret_type, class_name, name, __VA_ARGS__) \
throw std::runtime_error
("Tried to call pure virtual function \"" #name "\"");
pybind11::pybind11_fail
("Tried to call pure virtual function \"" #name "\"");
NAMESPACE_END
(
pybind11
)
NAMESPACE_END
(
pybind11
)
...
...
include/pybind11/pytypes.h
View file @
678d787c
This diff is collapsed.
Click to expand it.
include/pybind11/stl.h
View file @
678d787c
...
@@ -14,7 +14,6 @@
...
@@ -14,7 +14,6 @@
#include <set>
#include <set>
#include <iostream>
#include <iostream>
#if defined(_MSC_VER)
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(push)
#pragma warning(disable: 4127) // warning C4127: Conditional expression is constant
#pragma warning(disable: 4127) // warning C4127: Conditional expression is constant
...
@@ -28,14 +27,14 @@ template <typename Value, typename Alloc> struct type_caster<std::vector<Value,
...
@@ -28,14 +27,14 @@ template <typename Value, typename Alloc> struct type_caster<std::vector<Value,
typedef
type_caster
<
Value
>
value_conv
;
typedef
type_caster
<
Value
>
value_conv
;
public
:
public
:
bool
load
(
PyObject
*
src
,
bool
convert
)
{
bool
load
(
PyObject
*
src
,
bool
convert
)
{
if
(
!
PyList_Check
(
src
))
list
l
(
src
,
true
);
if
(
!
l
.
check
())
return
false
;
return
false
;
size_t
size
=
(
size_t
)
PyList_GET_SIZE
(
src
);
value
.
reserve
(
l
.
size
());
value
.
reserve
(
size
);
value
.
clear
();
value
.
clear
();
value_conv
conv
;
value_conv
conv
;
for
(
size_t
i
=
0
;
i
<
size
;
++
i
)
{
for
(
auto
it
:
l
)
{
if
(
!
conv
.
load
(
PyList_GetItem
(
src
,
(
ssize_t
)
i
),
convert
))
if
(
!
conv
.
load
(
it
.
ptr
(
),
convert
))
return
false
;
return
false
;
value
.
push_back
((
Value
)
conv
);
value
.
push_back
((
Value
)
conv
);
}
}
...
@@ -43,17 +42,15 @@ public:
...
@@ -43,17 +42,15 @@ public:
}
}
static
PyObject
*
cast
(
const
type
&
src
,
return_value_policy
policy
,
PyObject
*
parent
)
{
static
PyObject
*
cast
(
const
type
&
src
,
return_value_policy
policy
,
PyObject
*
parent
)
{
object
list
(
PyList_New
(
src
.
size
()),
false
);
list
l
(
src
.
size
());
if
(
!
list
)
return
nullptr
;
size_t
index
=
0
;
size_t
index
=
0
;
for
(
auto
const
&
value
:
src
)
{
for
(
auto
const
&
value
:
src
)
{
object
value_
(
value_conv
::
cast
(
value
,
policy
,
parent
),
false
);
object
value_
(
value_conv
::
cast
(
value
,
policy
,
parent
),
false
);
if
(
!
value_
)
if
(
!
value_
)
return
nullptr
;
return
nullptr
;
PyList_SET_ITEM
(
l
ist
.
ptr
(),
index
++
,
value_
.
release
());
// steals a reference
PyList_SET_ITEM
(
l
.
ptr
(),
index
++
,
value_
.
release
());
// steals a reference
}
}
return
l
ist
.
release
();
return
l
.
release
();
}
}
PYBIND11_TYPE_CASTER
(
type
,
_
(
"list<"
)
+
value_conv
::
name
()
+
_
(
">"
));
PYBIND11_TYPE_CASTER
(
type
,
_
(
"list<"
)
+
value_conv
::
name
()
+
_
(
">"
));
};
};
...
@@ -68,8 +65,8 @@ public:
...
@@ -68,8 +65,8 @@ public:
return
false
;
return
false
;
value
.
clear
();
value
.
clear
();
key_conv
conv
;
key_conv
conv
;
for
(
const
object
&
o
:
s
)
{
for
(
auto
entry
:
s
)
{
if
(
!
conv
.
load
(
(
PyObject
*
)
o
.
ptr
(),
convert
))
if
(
!
conv
.
load
(
entry
.
ptr
(),
convert
))
return
false
;
return
false
;
value
.
insert
((
Key
)
conv
);
value
.
insert
((
Key
)
conv
);
}
}
...
@@ -77,15 +74,13 @@ public:
...
@@ -77,15 +74,13 @@ public:
}
}
static
PyObject
*
cast
(
const
type
&
src
,
return_value_policy
policy
,
PyObject
*
parent
)
{
static
PyObject
*
cast
(
const
type
&
src
,
return_value_policy
policy
,
PyObject
*
parent
)
{
object
set
(
PySet_New
(
nullptr
),
false
);
pybind11
::
set
s
;
if
(
!
set
)
return
nullptr
;
for
(
auto
const
&
value
:
src
)
{
for
(
auto
const
&
value
:
src
)
{
object
value_
(
key_conv
::
cast
(
value
,
policy
,
parent
),
false
);
object
value_
(
key_conv
::
cast
(
value
,
policy
,
parent
),
false
);
if
(
!
value_
||
PySet_Add
(
set
.
ptr
(),
value_
.
ptr
())
!=
0
)
if
(
!
value_
||
!
s
.
add
(
value
)
)
return
nullptr
;
return
nullptr
;
}
}
return
s
et
.
release
();
return
s
.
release
();
}
}
PYBIND11_TYPE_CASTER
(
type
,
_
(
"set<"
)
+
key_conv
::
name
()
+
_
(
">"
));
PYBIND11_TYPE_CASTER
(
type
,
_
(
"set<"
)
+
key_conv
::
name
()
+
_
(
">"
));
};
};
...
@@ -97,16 +92,15 @@ public:
...
@@ -97,16 +92,15 @@ public:
typedef
type_caster
<
Value
>
value_conv
;
typedef
type_caster
<
Value
>
value_conv
;
bool
load
(
PyObject
*
src
,
bool
convert
)
{
bool
load
(
PyObject
*
src
,
bool
convert
)
{
if
(
!
PyDict_Check
(
src
))
dict
d
(
src
,
true
);
if
(
!
d
.
check
())
return
false
;
return
false
;
value
.
clear
();
PyObject
*
key_
,
*
value_
;
ssize_t
pos
=
0
;
key_conv
kconv
;
key_conv
kconv
;
value_conv
vconv
;
value_conv
vconv
;
while
(
PyDict_Next
(
src
,
&
pos
,
&
key_
,
&
value_
))
{
value
.
clear
();
if
(
!
kconv
.
load
(
key_
,
convert
)
||
!
vconv
.
load
(
value_
,
convert
))
for
(
auto
it
:
d
)
{
if
(
!
kconv
.
load
(
it
.
first
.
ptr
(),
convert
)
||
!
vconv
.
load
(
it
.
second
.
ptr
(),
convert
))
return
false
;
return
false
;
value
[(
Key
)
kconv
]
=
(
Value
)
vconv
;
value
[(
Key
)
kconv
]
=
(
Value
)
vconv
;
}
}
...
@@ -114,16 +108,15 @@ public:
...
@@ -114,16 +108,15 @@ public:
}
}
static
PyObject
*
cast
(
const
type
&
src
,
return_value_policy
policy
,
PyObject
*
parent
)
{
static
PyObject
*
cast
(
const
type
&
src
,
return_value_policy
policy
,
PyObject
*
parent
)
{
object
dict
(
PyDict_New
(),
false
);
dict
d
;
if
(
!
dict
)
return
nullptr
;
for
(
auto
const
&
kv
:
src
)
{
for
(
auto
const
&
kv
:
src
)
{
object
key
(
key_conv
::
cast
(
kv
.
first
,
policy
,
parent
),
false
);
object
key
(
key_conv
::
cast
(
kv
.
first
,
policy
,
parent
),
false
);
object
value
(
value_conv
::
cast
(
kv
.
second
,
policy
,
parent
),
false
);
object
value
(
value_conv
::
cast
(
kv
.
second
,
policy
,
parent
),
false
);
if
(
!
key
||
!
value
||
PyDict_SetItem
(
dict
.
ptr
(),
key
.
ptr
(),
value
.
ptr
())
!=
0
)
if
(
!
key
||
!
value
)
return
nullptr
;
return
nullptr
;
d
[
key
]
=
value
;
}
}
return
d
ict
.
release
();
return
d
.
release
();
}
}
PYBIND11_TYPE_CASTER
(
type
,
_
(
"dict<"
)
+
key_conv
::
name
()
+
_
(
", "
)
+
value_conv
::
name
()
+
_
(
">"
));
PYBIND11_TYPE_CASTER
(
type
,
_
(
"dict<"
)
+
key_conv
::
name
()
+
_
(
", "
)
+
value_conv
::
name
()
+
_
(
">"
));
...
@@ -131,7 +124,10 @@ public:
...
@@ -131,7 +124,10 @@ public:
NAMESPACE_END
(
detail
)
NAMESPACE_END
(
detail
)
inline
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
object
&
obj
)
{
os
<<
(
std
::
string
)
obj
.
str
();
return
os
;
}
inline
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
handle
&
obj
)
{
os
<<
(
std
::
string
)
obj
.
str
();
return
os
;
}
NAMESPACE_END
(
pybind11
)
NAMESPACE_END
(
pybind11
)
...
...
include/pybind11/typeid.h
View file @
678d787c
...
@@ -11,6 +11,7 @@
...
@@ -11,6 +11,7 @@
#include <cstdio>
#include <cstdio>
#include <cstdlib>
#include <cstdlib>
#if defined(__GNUG__)
#if defined(__GNUG__)
#include <cxxabi.h>
#include <cxxabi.h>
#endif
#endif
...
@@ -26,7 +27,7 @@ inline void erase_all(std::string &string, const std::string &search) {
...
@@ -26,7 +27,7 @@ inline void erase_all(std::string &string, const std::string &search) {
}
}
}
}
inline
void
clean_type_id
(
std
::
string
&
name
)
{
PYBIND11_NOINLINE
inline
void
clean_type_id
(
std
::
string
&
name
)
{
#if defined(__GNUG__)
#if defined(__GNUG__)
int
status
=
0
;
int
status
=
0
;
std
::
unique_ptr
<
char
,
void
(
*
)(
void
*
)
>
res
{
std
::
unique_ptr
<
char
,
void
(
*
)(
void
*
)
>
res
{
...
...
setup.py
View file @
678d787c
...
@@ -17,6 +17,7 @@ setup(
...
@@ -17,6 +17,7 @@ setup(
headers
=
[
headers
=
[
'include/pybind11/cast.h'
,
'include/pybind11/cast.h'
,
'include/pybind11/complex.h'
,
'include/pybind11/complex.h'
,
'include/pybind11/descr.h'
,
'include/pybind11/numpy.h'
,
'include/pybind11/numpy.h'
,
'include/pybind11/pybind11.h'
,
'include/pybind11/pybind11.h'
,
'include/pybind11/stl.h'
,
'include/pybind11/stl.h'
,
...
@@ -57,11 +58,10 @@ C++11-compatible compilers are widely available, this heavy machinery has
...
@@ -57,11 +58,10 @@ C++11-compatible compilers are widely available, this heavy machinery has
become an excessively large and unnecessary dependency.
become an excessively large and unnecessary dependency.
Think of this library as a tiny self-contained version of Boost.Python with
Think of this library as a tiny self-contained version of Boost.Python with
everything stripped away that isn't relevant for binding generation. The whole
everything stripped away that isn't relevant for binding generation. The core
codebase requires less than 3000 lines of code and only depends on Python (2.7
header files only require ~2.5K lines of code and depend on Python (2.7 or 3.x)
or 3.x) and the C++ standard library. This compact implementation was
and the C++ standard library. This compact implementation was possible thanks
possible thanks to some of the new C++11 language features (tuples, lambda
to some of the new C++11 language features (specifically: tuples, lambda
functions and variadic templates). Since its creation, this library has
functions and variadic templates). Since its creation, this library has grown
grown beyond Boost.Python in many ways, leading to dramatically simpler binding
beyond Boost.Python in many ways, leading to dramatically simpler binding code
code in many common situations."""
,
in many common situations."""
)
)
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