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
ea763a57
Commit
ea763a57
authored
Sep 22, 2016
by
Dean Moldovan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Extend tuple and list accessor interface
parent
242b146a
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
49 additions
and
44 deletions
+49
-44
include/pybind11/pybind11.h
+1
-1
include/pybind11/pytypes.h
+29
-41
tests/test_python_types.cpp
+16
-1
tests/test_python_types.py
+3
-1
No files found.
include/pybind11/pybind11.h
View file @
ea763a57
...
...
@@ -1338,7 +1338,7 @@ NAMESPACE_BEGIN(detail)
PYBIND11_NOINLINE
inline
void
print
(
tuple
args
,
dict
kwargs
)
{
auto
strings
=
tuple
(
args
.
size
());
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
line
=
sep
.
attr
(
"join"
)(
strings
);
...
...
include/pybind11/pytypes.h
View file @
ea763a57
...
...
@@ -29,10 +29,14 @@ namespace accessor_policies {
struct
obj_attr
;
struct
str_attr
;
struct
generic_item
;
struct
list_item
;
struct
tuple_item
;
}
using
obj_attr_accessor
=
accessor
<
accessor_policies
::
obj_attr
>
;
using
str_attr_accessor
=
accessor
<
accessor_policies
::
str_attr
>
;
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
class
pyobject_tag
{
};
...
...
@@ -241,57 +245,41 @@ struct generic_item {
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
)
{
// PyList_SetItem steals a reference to 'o'
if
(
PyList_SetItem
(
list
.
ptr
(),
(
ssize_t
)
index
,
o
.
inc_ref
().
ptr
())
<
0
)
pybind11_fail
(
"Unable to assign value in Python list!"
)
;
static
object
get
(
handle
obj
,
size_t
index
)
{
PyObject
*
result
=
PyList_GetItem
(
obj
.
ptr
(),
static_cast
<
ssize_t
>
(
index
));
if
(
!
result
)
{
throw
error_already_set
();
}
return
{
result
,
true
}
;
}
operator
object
()
const
{
PyObject
*
result
=
PyList_GetItem
(
list
.
ptr
(),
(
ssize_t
)
index
);
if
(
!
result
)
pybind11_fail
(
"Unable to retrieve value from Python list!"
);
return
object
(
result
,
true
);
static
void
set
(
handle
obj
,
size_t
index
,
handle
val
)
{
// PyList_SetItem steals a reference to 'val'
if
(
PyList_SetItem
(
obj
.
ptr
(),
static_cast
<
ssize_t
>
(
index
),
val
.
inc_ref
().
ptr
())
!=
0
)
{
throw
error_already_set
(
);
}
}
template
<
typename
T
>
T
cast
()
const
{
return
operator
object
().
cast
<
T
>
();
}
private
:
handle
list
;
size_t
index
;
};
struct
tuple_accessor
{
public
:
tuple_accessor
(
handle
tuple
,
size_t
index
)
:
tuple
(
tuple
),
index
(
index
)
{
}
void
operator
=
(
tuple_accessor
o
)
{
return
operator
=
(
object
(
o
));
}
struct
tuple_item
{
using
key_type
=
size_t
;
void
operator
=
(
const
handle
&
o
)
{
// PyTuple_SetItem steals a referenceto 'o'
if
(
PyTuple_SetItem
(
tuple
.
ptr
(),
(
ssize_t
)
index
,
o
.
inc_ref
().
ptr
())
<
0
)
pybind11_fail
(
"Unable to assign value in Python tuple!"
)
;
static
object
get
(
handle
obj
,
size_t
index
)
{
PyObject
*
result
=
PyTuple_GetItem
(
obj
.
ptr
(),
static_cast
<
ssize_t
>
(
index
));
if
(
!
result
)
{
throw
error_already_set
();
}
return
{
result
,
true
}
;
}
operator
object
()
const
{
PyObject
*
result
=
PyTuple_GetItem
(
tuple
.
ptr
(),
(
ssize_t
)
index
);
if
(
!
result
)
pybind11_fail
(
"Unable to retrieve value from Python tuple!"
);
return
object
(
result
,
true
);
static
void
set
(
handle
obj
,
size_t
index
,
handle
val
)
{
// PyTuple_SetItem steals a reference to 'val'
if
(
PyTuple_SetItem
(
obj
.
ptr
(),
static_cast
<
ssize_t
>
(
index
),
val
.
inc_ref
().
ptr
())
!=
0
)
{
throw
error_already_set
(
);
}
}
template
<
typename
T
>
T
cast
()
const
{
return
operator
object
().
cast
<
T
>
();
}
private
:
handle
tuple
;
size_t
index
;
};
NAMESPACE_END
(
accessor_policies
)
struct
dict_iterator
{
public
:
...
...
@@ -647,7 +635,7 @@ public:
if
(
!
m_ptr
)
pybind11_fail
(
"Could not allocate tuple object!"
);
}
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
{
...
...
@@ -677,7 +665,7 @@ public:
if
(
!
m_ptr
)
pybind11_fail
(
"Could not allocate list object!"
);
}
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
());
}
};
...
...
tests/test_python_types.cpp
View file @
ea763a57
...
...
@@ -60,7 +60,7 @@ public:
py
::
list
get_list
()
{
py
::
list
list
;
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"
);
return
list
;
}
...
...
@@ -257,4 +257,19 @@ test_initializer python_types([](py::module &m) {
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():
def
test_accessors
():
from
pybind11_tests
import
test_accessor_api
from
pybind11_tests
import
test_accessor_api
,
test_tuple_accessor
class
SubTestObject
:
attr_obj
=
1
...
...
@@ -278,3 +278,5 @@ def test_accessors():
assert
d
[
"is_none"
]
is
False
assert
d
[
"operator()"
]
==
2
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