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)
...
@@ -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_SetItem steals a reference to 'o'
PyObject
*
result
=
PyList_GetItem
(
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_GetItem
(
list
.
ptr
(),
(
ssize_t
)
index
);
// PyList_SetItem 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_SetItem steals a referenceto 'o'
PyObject
*
result
=
PyTuple_GetItem
(
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_GetItem
(
tuple
.
ptr
(),
(
ssize_t
)
index
);
// PyTuple_SetItem 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