Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
gaoqiong
pybind11
Commits
deadbbb6
Commit
deadbbb6
authored
Jan 07, 2016
by
Wenzel Jakob
Browse files
Merge pull request #57 from tmiasko/conversion
Use object class to hold partially converted python objects.
parents
3367cecc
ca77130b
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
63 additions
and
71 deletions
+63
-71
docs/reference.rst
docs/reference.rst
+7
-1
include/pybind11/cast.h
include/pybind11/cast.h
+29
-42
include/pybind11/pytypes.h
include/pybind11/pytypes.h
+7
-2
include/pybind11/stl.h
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
<
PyO
bject
*
,
size
>
results
{{
std
::
array
<
o
bject
,
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
<
PyO
bject
*
,
size
>
args
{
std
::
array
<
o
bject
,
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