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
deadbbb6
Commit
deadbbb6
authored
Jan 07, 2016
by
Wenzel Jakob
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #57 from tmiasko/conversion
Use object class to hold partially converted python objects.
parents
3367cecc
ca77130b
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
63 additions
and
71 deletions
+63
-71
docs/reference.rst
+7
-1
include/pybind11/cast.h
+29
-42
include/pybind11/pytypes.h
+7
-2
include/pybind11/stl.h
+20
-26
No files found.
docs/reference.rst
View file @
deadbbb6
...
@@ -59,7 +59,7 @@ Without reference counting
...
@@ -59,7 +59,7 @@ Without reference counting
Creates a :class:`handle` from the given raw Python object pointer.
Creates a :class:`handle` from the given raw Python object pointer.
.. function:: PyObject * handle::ptr()
.. function:: PyObject * handle::ptr()
const
Return the ``PyObject *`` underlying a :class:`handle`.
Return the ``PyObject *`` underlying a :class:`handle`.
...
@@ -167,6 +167,12 @@ With reference counting
...
@@ -167,6 +167,12 @@ With reference counting
Move constructor; steals the object from ``other`` and preserves its
Move constructor; steals the object from ``other`` and preserves its
reference count.
reference count.
.. function:: PyObject* object::release()
Release ownership of underlying ``PyObject *``. Returns raw Python object
pointer without decreasing its reference count and resets handle to
``nullptr``-valued pointer.
.. function:: object::~object()
.. function:: object::~object()
Constructor, which automatically calls :func:`handle::dec_ref()`.
Constructor, which automatically calls :func:`handle::dec_ref()`.
...
...
include/pybind11/cast.h
View file @
deadbbb6
...
@@ -398,16 +398,15 @@ public:
...
@@ -398,16 +398,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
)
{
PyObject
*
o1
=
type_caster
<
typename
decay
<
T1
>::
type
>::
cast
(
src
.
first
,
policy
,
parent
);
object
o1
(
type_caster
<
typename
decay
<
T1
>::
type
>::
cast
(
src
.
first
,
policy
,
parent
),
false
);
PyObject
*
o2
=
type_caster
<
typename
decay
<
T2
>::
type
>::
cast
(
src
.
second
,
policy
,
parent
);
object
o2
(
type_caster
<
typename
decay
<
T2
>::
type
>::
cast
(
src
.
second
,
policy
,
parent
),
false
);
if
(
!
o1
||
!
o2
)
{
if
(
!
o1
||
!
o2
)
Py_XDECREF
(
o1
);
Py_XDECREF
(
o2
);
return
nullptr
;
return
nullptr
;
}
PyObject
*
tuple
=
PyTuple_New
(
2
);
PyObject
*
tuple
=
PyTuple_New
(
2
);
PyTuple_SetItem
(
tuple
,
0
,
o1
);
if
(
!
tuple
)
PyTuple_SetItem
(
tuple
,
1
,
o2
);
return
nullptr
;
PyTuple_SetItem
(
tuple
,
0
,
o1
.
release
());
PyTuple_SetItem
(
tuple
,
1
,
o2
.
release
());
return
tuple
;
return
tuple
;
}
}
...
@@ -502,25 +501,19 @@ protected:
...
@@ -502,25 +501,19 @@ protected:
/* Implementation: Convert a C++ tuple into a Python tuple */
/* Implementation: Convert a C++ tuple into a Python tuple */
template
<
size_t
...
Indices
>
static
PyObject
*
cast
(
const
type
&
src
,
return_value_policy
policy
,
PyObject
*
parent
,
index_sequence
<
Indices
...
>
)
{
template
<
size_t
...
Indices
>
static
PyObject
*
cast
(
const
type
&
src
,
return_value_policy
policy
,
PyObject
*
parent
,
index_sequence
<
Indices
...
>
)
{
std
::
array
<
PyObject
*
,
size
>
results
{{
std
::
array
<
object
,
size
>
results
{{
type_caster
<
typename
decay
<
Tuple
>::
type
>::
cast
(
std
::
get
<
Indices
>
(
src
),
policy
,
parent
)...
object
(
type_caster
<
typename
decay
<
Tuple
>::
type
>::
cast
(
std
::
get
<
Indices
>
(
src
),
policy
,
parent
),
false
)...
}};
}};
bool
success
=
true
;
for
(
const
auto
&
result
:
results
)
for
(
auto
result
:
results
)
if
(
!
result
)
if
(
result
==
nullptr
)
return
nullptr
;
success
=
false
;
PyObject
*
tuple
=
PyTuple_New
(
size
);
if
(
success
)
{
if
(
!
tuple
)
PyObject
*
tuple
=
PyTuple_New
(
size
);
int
counter
=
0
;
for
(
auto
result
:
results
)
PyTuple_SetItem
(
tuple
,
counter
++
,
result
);
return
tuple
;
}
else
{
for
(
auto
result
:
results
)
{
Py_XDECREF
(
result
);
}
return
nullptr
;
return
nullptr
;
}
int
counter
=
0
;
for
(
auto
&
result
:
results
)
PyTuple_SetItem
(
tuple
,
counter
++
,
result
.
release
());
return
tuple
;
}
}
protected
:
protected
:
...
@@ -600,26 +593,20 @@ template <> inline void handle::cast() const { return; }
...
@@ -600,26 +593,20 @@ template <> inline void handle::cast() const { return; }
template
<
typename
...
Args
>
inline
object
handle
::
call
(
Args
&&
...
args_
)
{
template
<
typename
...
Args
>
inline
object
handle
::
call
(
Args
&&
...
args_
)
{
const
size_t
size
=
sizeof
...(
Args
);
const
size_t
size
=
sizeof
...(
Args
);
std
::
array
<
PyObject
*
,
size
>
args
{
std
::
array
<
object
,
size
>
args
{
{
detail
::
type_caster
<
typename
detail
::
decay
<
Args
>::
type
>::
cast
(
{
object
(
detail
::
type_caster
<
typename
detail
::
decay
<
Args
>::
type
>::
cast
(
std
::
forward
<
Args
>
(
args_
),
return_value_policy
::
reference
,
nullptr
)...
}
std
::
forward
<
Args
>
(
args_
),
return_value_policy
::
reference
,
nullptr
)
,
false
)
...
}
};
};
bool
fail
=
false
;
for
(
const
auto
&
result
:
args
)
for
(
auto
result
:
args
)
if
(
!
result
)
if
(
result
==
nullptr
)
throw
cast_error
(
"handle::call(): unable to convert input arguments to Python objects"
);
fail
=
true
;
object
tuple
(
PyTuple_New
(
size
),
false
);
if
(
fail
)
{
if
(
!
tuple
)
for
(
auto
result
:
args
)
{
Py_XDECREF
(
result
);
}
throw
cast_error
(
"handle::call(): unable to convert input arguments to Python objects"
);
throw
cast_error
(
"handle::call(): unable to convert input arguments to Python objects"
);
}
PyObject
*
tuple
=
PyTuple_New
(
size
);
int
counter
=
0
;
int
counter
=
0
;
for
(
auto
result
:
args
)
for
(
auto
&
result
:
args
)
PyTuple_SetItem
(
tuple
,
counter
++
,
result
);
PyTuple_SetItem
(
tuple
.
ptr
(),
counter
++
,
result
.
release
());
PyObject
*
result
=
PyObject_CallObject
(
m_ptr
,
tuple
);
PyObject
*
result
=
PyObject_CallObject
(
m_ptr
,
tuple
.
ptr
());
Py_DECREF
(
tuple
);
if
(
result
==
nullptr
&&
PyErr_Occurred
())
if
(
result
==
nullptr
&&
PyErr_Occurred
())
throw
error_already_set
();
throw
error_already_set
();
return
object
(
result
,
false
);
return
object
(
result
,
false
);
...
...
include/pybind11/pytypes.h
View file @
deadbbb6
...
@@ -29,8 +29,7 @@ public:
...
@@ -29,8 +29,7 @@ public:
handle
()
:
m_ptr
(
nullptr
)
{
}
handle
()
:
m_ptr
(
nullptr
)
{
}
handle
(
const
handle
&
other
)
:
m_ptr
(
other
.
m_ptr
)
{
}
handle
(
const
handle
&
other
)
:
m_ptr
(
other
.
m_ptr
)
{
}
handle
(
PyObject
*
ptr
)
:
m_ptr
(
ptr
)
{
}
handle
(
PyObject
*
ptr
)
:
m_ptr
(
ptr
)
{
}
PyObject
*
ptr
()
{
return
m_ptr
;
}
PyObject
*
ptr
()
const
{
return
m_ptr
;
}
const
PyObject
*
ptr
()
const
{
return
m_ptr
;
}
void
inc_ref
()
const
{
Py_XINCREF
(
m_ptr
);
}
void
inc_ref
()
const
{
Py_XINCREF
(
m_ptr
);
}
void
dec_ref
()
const
{
Py_XDECREF
(
m_ptr
);
}
void
dec_ref
()
const
{
Py_XDECREF
(
m_ptr
);
}
int
ref_count
()
const
{
return
(
int
)
Py_REFCNT
(
m_ptr
);
}
int
ref_count
()
const
{
return
(
int
)
Py_REFCNT
(
m_ptr
);
}
...
@@ -60,6 +59,12 @@ public:
...
@@ -60,6 +59,12 @@ public:
object
(
object
&&
other
)
{
m_ptr
=
other
.
m_ptr
;
other
.
m_ptr
=
nullptr
;
}
object
(
object
&&
other
)
{
m_ptr
=
other
.
m_ptr
;
other
.
m_ptr
=
nullptr
;
}
~
object
()
{
dec_ref
();
}
~
object
()
{
dec_ref
();
}
PyObject
*
release
()
{
PyObject
*
tmp
=
m_ptr
;
m_ptr
=
nullptr
;
return
tmp
;
}
object
&
operator
=
(
object
&
other
)
{
object
&
operator
=
(
object
&
other
)
{
Py_XINCREF
(
other
.
m_ptr
);
Py_XINCREF
(
other
.
m_ptr
);
Py_XDECREF
(
m_ptr
);
Py_XDECREF
(
m_ptr
);
...
...
include/pybind11/stl.h
View file @
deadbbb6
...
@@ -43,17 +43,17 @@ public:
...
@@ -43,17 +43,17 @@ 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
)
{
PyObject
*
list
=
PyList_New
(
src
.
size
());
object
list
(
PyList_New
(
src
.
size
()),
false
);
if
(
!
list
)
return
nullptr
;
size_t
index
=
0
;
size_t
index
=
0
;
for
(
auto
const
&
value
:
src
)
{
for
(
auto
const
&
value
:
src
)
{
PyObject
*
value_
=
value_conv
::
cast
(
value
,
policy
,
parent
);
object
value_
(
value_conv
::
cast
(
value
,
policy
,
parent
),
false
);
if
(
!
value_
)
{
if
(
!
value_
)
Py_DECREF
(
list
);
return
nullptr
;
return
nullptr
;
}
PyList_SET_ITEM
(
list
.
ptr
(),
index
++
,
value_
.
release
());
// steals a reference
PyList_SET_ITEM
(
list
,
index
++
,
value_
);
// steals a reference
}
}
return
list
;
return
list
.
release
()
;
}
}
PYBIND11_TYPE_CASTER
(
type
,
detail
::
descr
(
"list<"
)
+
value_conv
::
name
()
+
detail
::
descr
(
">"
));
PYBIND11_TYPE_CASTER
(
type
,
detail
::
descr
(
"list<"
)
+
value_conv
::
name
()
+
detail
::
descr
(
">"
));
};
};
...
@@ -77,17 +77,15 @@ public:
...
@@ -77,17 +77,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
)
{
PyObject
*
set
=
PySet_New
(
nullptr
);
object
set
(
PySet_New
(
nullptr
),
false
);
if
(
!
set
)
return
nullptr
;
for
(
auto
const
&
value
:
src
)
{
for
(
auto
const
&
value
:
src
)
{
PyObject
*
value_
=
value_conv
::
cast
(
value
,
policy
,
parent
);
object
value_
(
value_conv
::
cast
(
value
,
policy
,
parent
),
false
);
if
(
!
value_
||
PySet_Add
(
set
,
value_
)
!=
0
)
{
if
(
!
value_
||
PySet_Add
(
set
.
ptr
(),
value_
.
ptr
())
!=
0
)
Py_XDECREF
(
value_
);
Py_DECREF
(
set
);
return
nullptr
;
return
nullptr
;
}
Py_DECREF
(
value_
);
}
}
return
set
;
return
set
.
release
()
;
}
}
PYBIND11_TYPE_CASTER
(
type
,
detail
::
descr
(
"set<"
)
+
value_conv
::
name
()
+
detail
::
descr
(
">"
));
PYBIND11_TYPE_CASTER
(
type
,
detail
::
descr
(
"set<"
)
+
value_conv
::
name
()
+
detail
::
descr
(
">"
));
};
};
...
@@ -116,20 +114,16 @@ public:
...
@@ -116,20 +114,16 @@ 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
)
{
PyObject
*
dict
=
PyDict_New
();
object
dict
(
PyDict_New
(),
false
);
if
(
!
dict
)
return
nullptr
;
for
(
auto
const
&
kv
:
src
)
{
for
(
auto
const
&
kv
:
src
)
{
PyObject
*
key
=
key_conv
::
cast
(
kv
.
first
,
policy
,
parent
);
object
key
(
key_conv
::
cast
(
kv
.
first
,
policy
,
parent
),
false
);
PyObject
*
value
=
value_conv
::
cast
(
kv
.
second
,
policy
,
parent
);
object
value
(
value_conv
::
cast
(
kv
.
second
,
policy
,
parent
),
false
);
if
(
!
key
||
!
value
||
PyDict_SetItem
(
dict
,
key
,
value
)
!=
0
)
{
if
(
!
key
||
!
value
||
PyDict_SetItem
(
dict
.
ptr
(),
key
.
ptr
(),
value
.
ptr
())
!=
0
)
Py_XDECREF
(
key
);
Py_XDECREF
(
value
);
Py_DECREF
(
dict
);
return
nullptr
;
return
nullptr
;
}
Py_DECREF
(
key
);
Py_DECREF
(
value
);
}
}
return
dict
;
return
dict
.
release
()
;
}
}
PYBIND11_TYPE_CASTER
(
type
,
detail
::
descr
(
"dict<"
)
+
key_conv
::
name
()
+
detail
::
descr
(
", "
)
+
value_conv
::
name
()
+
detail
::
descr
(
">"
));
PYBIND11_TYPE_CASTER
(
type
,
detail
::
descr
(
"dict<"
)
+
key_conv
::
name
()
+
detail
::
descr
(
", "
)
+
value_conv
::
name
()
+
detail
::
descr
(
">"
));
...
...
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