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
ea763a57
"tests/git@developer.sourcefind.cn:gaoqiong/pybind11.git" did not exist on "afdc09deda50d82eba6cc2e48228df7d909650be"
Commit
ea763a57
authored
Sep 22, 2016
by
Dean Moldovan
Browse files
Extend tuple and list accessor interface
parent
242b146a
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
49 additions
and
44 deletions
+49
-44
include/pybind11/pybind11.h
include/pybind11/pybind11.h
+1
-1
include/pybind11/pytypes.h
include/pybind11/pytypes.h
+29
-41
tests/test_python_types.cpp
tests/test_python_types.cpp
+16
-1
tests/test_python_types.py
tests/test_python_types.py
+3
-1
No files found.
include/pybind11/pybind11.h
View file @
ea763a57
...
@@ -1338,7 +1338,7 @@ NAMESPACE_BEGIN(detail)
...
@@ -1338,7 +1338,7 @@ NAMESPACE_BEGIN(detail)
PYBIND11_NOINLINE
inline
void
print
(
tuple
args
,
dict
kwargs
)
{
PYBIND11_NOINLINE
inline
void
print
(
tuple
args
,
dict
kwargs
)
{
auto
strings
=
tuple
(
args
.
size
());
auto
strings
=
tuple
(
args
.
size
());
for
(
size_t
i
=
0
;
i
<
args
.
size
();
++
i
)
{
for
(
size_t
i
=
0
;
i
<
args
.
size
();
++
i
)
{
strings
[
i
]
=
args
[
i
].
cast
<
object
>
().
str
();
strings
[
i
]
=
args
[
i
].
str
();
}
}
auto
sep
=
kwargs
.
contains
(
"sep"
)
?
kwargs
[
"sep"
]
:
cast
(
" "
);
auto
sep
=
kwargs
.
contains
(
"sep"
)
?
kwargs
[
"sep"
]
:
cast
(
" "
);
auto
line
=
sep
.
attr
(
"join"
)(
strings
);
auto
line
=
sep
.
attr
(
"join"
)(
strings
);
...
...
include/pybind11/pytypes.h
View file @
ea763a57
...
@@ -29,10 +29,14 @@ namespace accessor_policies {
...
@@ -29,10 +29,14 @@ namespace accessor_policies {
struct
obj_attr
;
struct
obj_attr
;
struct
str_attr
;
struct
str_attr
;
struct
generic_item
;
struct
generic_item
;
struct
list_item
;
struct
tuple_item
;
}
}
using
obj_attr_accessor
=
accessor
<
accessor_policies
::
obj_attr
>
;
using
obj_attr_accessor
=
accessor
<
accessor_policies
::
obj_attr
>
;
using
str_attr_accessor
=
accessor
<
accessor_policies
::
str_attr
>
;
using
str_attr_accessor
=
accessor
<
accessor_policies
::
str_attr
>
;
using
item_accessor
=
accessor
<
accessor_policies
::
generic_item
>
;
using
item_accessor
=
accessor
<
accessor_policies
::
generic_item
>
;
using
list_accessor
=
accessor
<
accessor_policies
::
list_item
>
;
using
tuple_accessor
=
accessor
<
accessor_policies
::
tuple_item
>
;
/// Tag and check to identify a class which implements the Python object API
/// Tag and check to identify a class which implements the Python object API
class
pyobject_tag
{
};
class
pyobject_tag
{
};
...
@@ -241,57 +245,41 @@ struct generic_item {
...
@@ -241,57 +245,41 @@ struct generic_item {
if
(
PyObject_SetItem
(
obj
.
ptr
(),
key
.
ptr
(),
val
.
ptr
())
!=
0
)
{
throw
error_already_set
();
}
if
(
PyObject_SetItem
(
obj
.
ptr
(),
key
.
ptr
(),
val
.
ptr
())
!=
0
)
{
throw
error_already_set
();
}
}
}
};
};
NAMESPACE_END
(
accessor_policies
)
struct
list_accessor
{
public:
list_accessor
(
handle
list
,
size_t
index
)
:
list
(
list
),
index
(
index
)
{
}
void
operator
=
(
list_accessor
o
)
{
return
operator
=
(
object
(
o
));
}
struct
list_item
{
using
key_type
=
size_t
;
void
operator
=
(
const
handle
&
o
)
{
static
object
get
(
handle
obj
,
size_t
index
)
{
//
PyList_
S
etItem
steals a reference to 'o'
PyObject
*
result
=
PyList_
G
etItem
(
obj
.
ptr
(),
static_cast
<
ssize_t
>
(
index
));
if
(
PyList_SetItem
(
list
.
ptr
(),
(
ssize_t
)
index
,
o
.
inc_ref
().
ptr
())
<
0
)
if
(
!
result
)
{
throw
error_already_set
();
}
pybind11_fail
(
"Unable to assign value in Python list!"
)
;
return
{
result
,
true
}
;
}
}
operator
object
()
const
{
static
void
set
(
handle
obj
,
size_t
index
,
handle
val
)
{
PyObject
*
result
=
PyList_
G
etItem
(
list
.
ptr
(),
(
ssize_t
)
index
);
//
PyList_
S
etItem
steals a reference to 'val'
if
(
!
result
)
if
(
PyList_SetItem
(
obj
.
ptr
(),
static_cast
<
ssize_t
>
(
index
),
val
.
inc_ref
().
ptr
())
!=
0
)
{
pybind11_fail
(
"Unable to retrieve value from Python list!"
);
throw
error_already_set
(
);
return
object
(
result
,
true
);
}
}
}
template
<
typename
T
>
T
cast
()
const
{
return
operator
object
().
cast
<
T
>
();
}
private:
handle
list
;
size_t
index
;
};
};
struct
tuple_accessor
{
struct
tuple_item
{
public:
using
key_type
=
size_t
;
tuple_accessor
(
handle
tuple
,
size_t
index
)
:
tuple
(
tuple
),
index
(
index
)
{
}
void
operator
=
(
tuple_accessor
o
)
{
return
operator
=
(
object
(
o
));
}
void
operator
=
(
const
handle
&
o
)
{
static
object
get
(
handle
obj
,
size_t
index
)
{
//
PyTuple_
S
etItem
steals a referenceto 'o'
PyObject
*
result
=
PyTuple_
G
etItem
(
obj
.
ptr
(),
static_cast
<
ssize_t
>
(
index
));
if
(
PyTuple_SetItem
(
tuple
.
ptr
(),
(
ssize_t
)
index
,
o
.
inc_ref
().
ptr
())
<
0
)
if
(
!
result
)
{
throw
error_already_set
();
}
pybind11_fail
(
"Unable to assign value in Python tuple!"
)
;
return
{
result
,
true
}
;
}
}
operator
object
()
const
{
static
void
set
(
handle
obj
,
size_t
index
,
handle
val
)
{
PyObject
*
result
=
PyTuple_
G
etItem
(
tuple
.
ptr
(),
(
ssize_t
)
index
);
//
PyTuple_
S
etItem
steals a reference to 'val'
if
(
!
result
)
if
(
PyTuple_SetItem
(
obj
.
ptr
(),
static_cast
<
ssize_t
>
(
index
),
val
.
inc_ref
().
ptr
())
!=
0
)
{
pybind11_fail
(
"Unable to retrieve value from Python tuple!"
);
throw
error_already_set
(
);
return
object
(
result
,
true
);
}
}
}
template
<
typename
T
>
T
cast
()
const
{
return
operator
object
().
cast
<
T
>
();
}
private:
handle
tuple
;
size_t
index
;
};
};
NAMESPACE_END
(
accessor_policies
)
struct
dict_iterator
{
struct
dict_iterator
{
public:
public:
...
@@ -647,7 +635,7 @@ public:
...
@@ -647,7 +635,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
(
*
this
,
index
)
;
}
detail
::
tuple_accessor
operator
[](
size_t
index
)
const
{
return
{
*
this
,
index
}
;
}
};
};
class
dict
:
public
object
{
class
dict
:
public
object
{
...
@@ -677,7 +665,7 @@ public:
...
@@ -677,7 +665,7 @@ public:
if
(
!
m_ptr
)
pybind11_fail
(
"Could not allocate list object!"
);
if
(
!
m_ptr
)
pybind11_fail
(
"Could not allocate list object!"
);
}
}
size_t
size
()
const
{
return
(
size_t
)
PyList_Size
(
m_ptr
);
}
size_t
size
()
const
{
return
(
size_t
)
PyList_Size
(
m_ptr
);
}
detail
::
list_accessor
operator
[](
size_t
index
)
const
{
return
detail
::
list_accessor
(
*
this
,
index
)
;
}
detail
::
list_accessor
operator
[](
size_t
index
)
const
{
return
{
*
this
,
index
}
;
}
void
append
(
handle
h
)
const
{
PyList_Append
(
m_ptr
,
h
.
ptr
());
}
void
append
(
handle
h
)
const
{
PyList_Append
(
m_ptr
,
h
.
ptr
());
}
};
};
...
...
tests/test_python_types.cpp
View file @
ea763a57
...
@@ -60,7 +60,7 @@ public:
...
@@ -60,7 +60,7 @@ public:
py
::
list
get_list
()
{
py
::
list
get_list
()
{
py
::
list
list
;
py
::
list
list
;
list
.
append
(
py
::
str
(
"value"
));
list
.
append
(
py
::
str
(
"value"
));
py
::
print
(
"Entry at position 0:"
,
py
::
object
(
list
[
0
])
)
;
py
::
print
(
"Entry at position 0:"
,
list
[
0
]);
list
[
0
]
=
py
::
str
(
"overwritten"
);
list
[
0
]
=
py
::
str
(
"overwritten"
);
return
list
;
return
list
;
}
}
...
@@ -257,4 +257,19 @@ test_initializer python_types([](py::module &m) {
...
@@ -257,4 +257,19 @@ test_initializer python_types([](py::module &m) {
return
d
;
return
d
;
});
});
m
.
def
(
"test_tuple_accessor"
,
[](
py
::
tuple
existing_t
)
{
try
{
existing_t
[
0
]
=
py
::
cast
(
1
);
}
catch
(
const
py
::
error_already_set
&
)
{
// --> Python system error
// Only new tuples (refcount == 1) are mutable
auto
new_t
=
py
::
tuple
(
3
);
for
(
size_t
i
=
0
;
i
<
new_t
.
size
();
++
i
)
{
new_t
[
i
]
=
py
::
cast
(
i
);
}
return
new_t
;
}
return
py
::
tuple
();
});
});
});
tests/test_python_types.py
View file @
ea763a57
...
@@ -251,7 +251,7 @@ def test_dict_api():
...
@@ -251,7 +251,7 @@ def test_dict_api():
def
test_accessors
():
def
test_accessors
():
from
pybind11_tests
import
test_accessor_api
from
pybind11_tests
import
test_accessor_api
,
test_tuple_accessor
class
SubTestObject
:
class
SubTestObject
:
attr_obj
=
1
attr_obj
=
1
...
@@ -278,3 +278,5 @@ def test_accessors():
...
@@ -278,3 +278,5 @@ def test_accessors():
assert
d
[
"is_none"
]
is
False
assert
d
[
"is_none"
]
is
False
assert
d
[
"operator()"
]
==
2
assert
d
[
"operator()"
]
==
2
assert
d
[
"operator*"
]
==
7
assert
d
[
"operator*"
]
==
7
assert
test_tuple_accessor
(
tuple
())
==
(
0
,
1
,
2
)
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