Skip to content

Commit

Permalink
Fold in PR pybind#3970 with #ifdefs
Browse files Browse the repository at this point in the history
  • Loading branch information
Ralf W. Grosse-Kunstleve committed May 28, 2022
1 parent 5fdfcdd commit 9758f6e
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 3 deletions.
58 changes: 56 additions & 2 deletions include/pybind11/pytypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,13 @@ class object_api : public pyobject_tag {
or `object` subclass causes a call to ``__setitem__``.
\endrst */
item_accessor operator[](handle key) const;
/// See above (the only difference is that they key is provided as a string literal)
#define PYBIND11_PR3970
#ifdef PYBIND11_PR3970
# define PYBIND11_PR3970_ITEM_ACCESSOR
/// See above (the only difference is that the key's reference is stolen)
item_accessor operator[](object &&key) const;
#endif
/// See above (the only difference is that the key is provided as a string literal)
item_accessor operator[](const char *key) const;

/** \rst
Expand All @@ -95,7 +101,12 @@ class object_api : public pyobject_tag {
or `object` subclass causes a call to ``setattr``.
\endrst */
obj_attr_accessor attr(handle key) const;
/// See above (the only difference is that they key is provided as a string literal)
/// See above (the only difference is that the key's reference is stolen)
#ifdef PYBIND11_PR3970
# define PYBIND11_PR3970_ATTR_ACCESSOR
obj_attr_accessor attr(object &&key) const;
/// See above (the only difference is that the key is provided as a string literal)
#endif
str_attr_accessor attr(const char *key) const;

/** \rst
Expand Down Expand Up @@ -676,7 +687,12 @@ class accessor : public object_api<accessor<Policy>> {
}
template <typename T>
void operator=(T &&value) & {
#ifdef PYBIND11_PR3970
# define PYBIND11_PR3970_ENSURE_OBJECT
get_cache() = ensure_object(object_or_cast(std::forward<T>(value)));
#else
get_cache() = reinterpret_borrow<object>(object_or_cast(std::forward<T>(value)));
#endif
}

template <typename T = Policy>
Expand Down Expand Up @@ -704,6 +720,11 @@ class accessor : public object_api<accessor<Policy>> {
}

private:
#ifdef PYBIND11_PR3970_ENSURE_OBJECT
static object ensure_object(object &&o) { return std::move(o); }
static object ensure_object(handle h) { return reinterpret_borrow<object>(h); }
#endif

object &get_cache() const {
if (!cache) {
cache = Policy::get(obj, key);
Expand Down Expand Up @@ -1703,7 +1724,14 @@ class tuple : public object {
size_t size() const { return (size_t) PyTuple_Size(m_ptr); }
bool empty() const { return size() == 0; }
detail::tuple_accessor operator[](size_t index) const { return {*this, index}; }
#ifdef PYBIND11_PR3970
template <typename T, detail::enable_if_t<detail::is_pyobject<T>::value, int> = 0>
detail::item_accessor operator[](T o) const {
return object::operator[](std::forward<T>(o));
}
#else
detail::item_accessor operator[](handle h) const { return object::operator[](h); }
#endif
detail::tuple_iterator begin() const { return {*this, 0}; }
detail::tuple_iterator end() const { return {*this, PyTuple_GET_SIZE(m_ptr)}; }
};
Expand Down Expand Up @@ -1763,7 +1791,14 @@ class sequence : public object {
}
bool empty() const { return size() == 0; }
detail::sequence_accessor operator[](size_t index) const { return {*this, index}; }
#ifdef PYBIND11_PR3970
template <typename T, detail::enable_if_t<detail::is_pyobject<T>::value, int> = 0>
detail::item_accessor operator[](T o) const {
return object::operator[](std::forward<T>(o));
}
#else
detail::item_accessor operator[](handle h) const { return object::operator[](h); }
#endif
detail::sequence_iterator begin() const { return {*this, 0}; }
detail::sequence_iterator end() const { return {*this, PySequence_Size(m_ptr)}; }
};
Expand All @@ -1782,7 +1817,14 @@ class list : public object {
size_t size() const { return (size_t) PyList_Size(m_ptr); }
bool empty() const { return size() == 0; }
detail::list_accessor operator[](size_t index) const { return {*this, index}; }
#ifdef PYBIND11_PR3970
template <typename T, detail::enable_if_t<detail::is_pyobject<T>::value, int> = 0>
detail::item_accessor operator[](T o) const {
return object::operator[](std::forward<T>(o));
}
#else
detail::item_accessor operator[](handle h) const { return object::operator[](h); }
#endif
detail::list_iterator begin() const { return {*this, 0}; }
detail::list_iterator end() const { return {*this, PyList_GET_SIZE(m_ptr)}; }
template <typename T>
Expand Down Expand Up @@ -2077,6 +2119,12 @@ template <typename D>
iterator object_api<D>::end() const {
return iterator::sentinel();
}
#ifdef PYBIND11_PR3970_ITEM_ACCESSOR
template <typename D>
item_accessor object_api<D>::operator[](object &&key) const {
return {derived(), std::move(key)};
}
#endif
template <typename D>
item_accessor object_api<D>::operator[](handle key) const {
return {derived(), reinterpret_borrow<object>(key)};
Expand All @@ -2085,6 +2133,12 @@ template <typename D>
item_accessor object_api<D>::operator[](const char *key) const {
return {derived(), pybind11::str(key)};
}
#ifdef PYBIND11_PR3970_ATTR_ACCESSOR
template <typename D>
obj_attr_accessor object_api<D>::attr(object &&key) const {
return {derived(), std::move(key)};
}
#endif
template <typename D>
obj_attr_accessor object_api<D>::attr(handle key) const {
return {derived(), reinterpret_borrow<object>(key)};
Expand Down
5 changes: 5 additions & 0 deletions tests/test_pytypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,11 @@ TEST_SUBMODULE(pytypes, m) {
m.def("accessor_moves", []() {
py::list return_list;
#ifdef PYBIND11_HANDLE_REF_DEBUG
# ifdef PYBIND11_PR3970
return_list.append("move");
# else
return_list.append("copy");
# endif
py::list lst;
lst.append(0);
auto list_accessor = lst[0];
Expand Down
5 changes: 4 additions & 1 deletion tests/test_pytypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,10 @@ def func(self, x, *args):
def test_accessor_moves():
inc_refs = m.accessor_moves()
if inc_refs:
assert inc_refs == [1, 1, 1, 1]
if inc_refs[0] == "copy":
assert inc_refs == ["copy", 1, 1, 1, 1]
else:
assert inc_refs == ["move", 1, 0, 1, 0]
else:
pytest.skip("Not defined: PYBIND11_HANDLE_REF_DEBUG")

Expand Down

0 comments on commit 9758f6e

Please sign in to comment.