Skip to content

Commit

Permalink
Enable building //third_party/clif/pybind11 with just the smart_hol…
Browse files Browse the repository at this point in the history
…der branch.

This is to support b/356954502: Move third_party/pybind11 back to smart_holder branch

It is/will still be possible to build with a pybind11 version that supports the PyCLIF-pybind11 unification. I.e. this command still passes:

```
blaze test third_party/clif/... devtools/clif/... --//devtools/clif/python/codegen_mode=pybind11
```

TGP-tested in combination with all CLs switching google3 back to the smart_holder branch:

* https://rwgk.users.x20web.corp.google.com/hg_xl_archive/hgx_back2sh2_as_of_2024-08-03%2B0756.txt

* http://tap/OCL:658995293:BASE:659091159:1722693935474:976f6583

PiperOrigin-RevId: 659890012
  • Loading branch information
rwgk committed Aug 27, 2024
1 parent 012f58e commit 172f312
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 62 deletions.
9 changes: 6 additions & 3 deletions clif/pybind11/clif_type_casters.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@

#include <vector>

#include "clif/pybind11/status_return_override.h"
#include "clif/python/postconv.h"
#include "clif/python/types.h"


namespace clif_pybind11 {

clif::py::PostConv PostConvFromReturnValuePolicyPack(
const pybind11::return_value_policy_pack& rvpp) {
clif::py::PostConv PostConvFromReturnValuePolicyPack(const rvp_or_rvpp& rvpp) {
#if defined(PYBIND11_HAS_RETURN_VALUE_POLICY_PACK)
if (rvpp.vec_rvpp.empty()) {
auto policy = pybind11::return_value_policy(rvpp);
if (policy == pybind11::return_value_policy::_return_as_bytes) {
Expand All @@ -37,6 +37,9 @@ clif::py::PostConv PostConvFromReturnValuePolicyPack(
post_conv.push_back(PostConvFromReturnValuePolicyPack(child_rvpp));
}
return clif::py::PostConv(post_conv);
#else
return clif::UnicodeFromBytesIfPossible;
#endif
}

} // namespace clif_pybind11
119 changes: 64 additions & 55 deletions clif/pybind11/clif_type_casters.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <type_traits>

#include "clif/pybind11/runtime.h"
#include "clif/pybind11/status_return_override.h"
#include "clif/python/postconv.h"
#include "clif/python/pyobject_ptr_conv.h"
#include "clif/python/types.h"
Expand Down Expand Up @@ -110,73 +111,81 @@ constexpr bool HasPyObjFrom() {

pybind11::object ReduceExImpl(pybind11::handle self, int protocol);

clif::py::PostConv PostConvFromReturnValuePolicyPack(
const pybind11::return_value_policy_pack& rvpp);
clif::py::PostConv PostConvFromReturnValuePolicyPack(const rvp_or_rvpp& rvpp);

} // namespace clif_pybind11

namespace pybind11 {
namespace detail {

#define CLIF_TYPE_CASTER_CAST \
template <class T = Type, \
std::enable_if_t<clif_pybind11::HasPyObjFrom<T>(), int> = 0> \
static handle cast(Type& src, const return_value_policy_pack& rvpp, \
handle /* parent */) { \
using ::clif::Clif_PyObjFrom; \
return Clif_PyObjFrom(std::move(src), \
clif_pybind11::PostConvFromReturnValuePolicyPack(rvpp)); \
} \
\
template <class T = Type, \
std::enable_if_t<clif_pybind11::HasPyObjFrom<T>(), int> = 0> \
static handle cast(const Type& src, const return_value_policy_pack& rvpp, \
handle /* parent */) { \
using ::clif::Clif_PyObjFrom; \
return Clif_PyObjFrom(std::move(src), \
clif_pybind11::PostConvFromReturnValuePolicyPack(rvpp)); \
} \
\
template <class T = Type, \
std::enable_if_t<clif_pybind11::HasPyObjFrom<T>(), int> = 0> \
static handle cast(Type&& src, const return_value_policy_pack& rvpp, \
handle /* parent */) { \
using ::clif::Clif_PyObjFrom; \
return Clif_PyObjFrom(std::move(src), \
clif_pybind11::PostConvFromReturnValuePolicyPack(rvpp)); \
} \
\
template <typename T = Type, \
std::enable_if_t<clif_pybind11::HasPyObjFrom<T*>(), int> = 0> \
static handle cast(Type* src, const return_value_policy_pack& rvpp, \
handle /* parent */) { \
using ::clif::Clif_PyObjFrom; \
return Clif_PyObjFrom(src, \
clif_pybind11::PostConvFromReturnValuePolicyPack(rvpp)); \
} \
\
template <typename T = Type, \
std::enable_if_t<clif_pybind11::HasPyObjFrom<T*>(), int> = 0> \
static handle cast(const Type* src, const return_value_policy_pack& rvpp, \
handle /* parent */) { \
using ::clif::Clif_PyObjFrom; \
return Clif_PyObjFrom(src, \
clif_pybind11::PostConvFromReturnValuePolicyPack(rvpp)); \
} \
\
template <typename T = Type, \
std::enable_if_t<clif_pybind11::HasPyObjFrom<T**>(), int> = 0> \
static handle cast(Type** src, const return_value_policy_pack& rvpp, \
handle /* parent */) { \
using ::clif::Clif_PyObjFrom; \
return Clif_PyObjFrom(src, \
clif_pybind11::PostConvFromReturnValuePolicyPack(rvpp)); \
#define CLIF_TYPE_CASTER_CAST \
template <class T = Type, \
std::enable_if_t<clif_pybind11::HasPyObjFrom<T>(), int> = 0> \
static handle cast(Type& src, const ::clif_pybind11::rvp_or_rvpp& rvpp, \
handle /* parent */) { \
using ::clif::Clif_PyObjFrom; \
return Clif_PyObjFrom( \
std::move(src), \
clif_pybind11::PostConvFromReturnValuePolicyPack(rvpp)); \
} \
\
template <class T = Type, \
std::enable_if_t<clif_pybind11::HasPyObjFrom<T>(), int> = 0> \
static handle cast(const Type& src, \
const ::clif_pybind11::rvp_or_rvpp& rvpp, \
handle /* parent */) { \
using ::clif::Clif_PyObjFrom; \
return Clif_PyObjFrom( \
std::move(src), \
clif_pybind11::PostConvFromReturnValuePolicyPack(rvpp)); \
} \
\
template <class T = Type, \
std::enable_if_t<clif_pybind11::HasPyObjFrom<T>(), int> = 0> \
static handle cast(Type&& src, const ::clif_pybind11::rvp_or_rvpp& rvpp, \
handle /* parent */) { \
using ::clif::Clif_PyObjFrom; \
return Clif_PyObjFrom( \
std::move(src), \
clif_pybind11::PostConvFromReturnValuePolicyPack(rvpp)); \
} \
\
template <typename T = Type, \
std::enable_if_t<clif_pybind11::HasPyObjFrom<T*>(), int> = 0> \
static handle cast(Type* src, const ::clif_pybind11::rvp_or_rvpp& rvpp, \
handle /* parent */) { \
using ::clif::Clif_PyObjFrom; \
return Clif_PyObjFrom( \
src, clif_pybind11::PostConvFromReturnValuePolicyPack(rvpp)); \
} \
\
template <typename T = Type, \
std::enable_if_t<clif_pybind11::HasPyObjFrom<T*>(), int> = 0> \
static handle cast(const Type* src, \
const ::clif_pybind11::rvp_or_rvpp& rvpp, \
handle /* parent */) { \
using ::clif::Clif_PyObjFrom; \
return Clif_PyObjFrom( \
src, clif_pybind11::PostConvFromReturnValuePolicyPack(rvpp)); \
} \
\
template <typename T = Type, \
std::enable_if_t<clif_pybind11::HasPyObjFrom<T**>(), int> = 0> \
static handle cast(Type** src, const ::clif_pybind11::rvp_or_rvpp& rvpp, \
handle /* parent */) { \
using ::clif::Clif_PyObjFrom; \
return Clif_PyObjFrom( \
src, clif_pybind11::PostConvFromReturnValuePolicyPack(rvpp)); \
}

template <class Type, typename SFINAE = void>
struct clif_type_caster {
public:
#if defined(PYBIND11_HAS_RETURN_VALUE_POLICY_PACK)
PYBIND11_TYPE_CASTER_RVPP(Type, const_name<Type>());
#else
PYBIND11_TYPE_CASTER(Type, const_name<Type>());
#endif

CLIF_TYPE_CASTER_CAST

Expand Down
6 changes: 6 additions & 0 deletions clif/pybind11/runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,19 @@ struct type_caster<clif::CapsuleWrapper<T>> {
value = clif::CapsuleWrapper<T>(reinterpret_borrow<capsule>(src.ptr()));
return true;
}
// This #if condition and the code below will need to be adapted, depending on
// the future of the PyCLIF-pybind11 unification.
#if defined(PYBIND11_HAS_RETURN_VALUE_POLICY_CLIF_AUTOMATIC)
// The implementation was in smart_holder_type_casters.h before it was
// removed with https://github.com/pybind/pybind11/pull/5257
void* void_ptr_from_void_ptr_capsule
= try_as_void_ptr_capsule_get_pointer(src, typeid(T).name());
if (void_ptr_from_void_ptr_capsule) {
value = clif::CapsuleWrapper<T>(
static_cast<T>(void_ptr_from_void_ptr_capsule));
return true;
}
#endif
return false;
}

Expand Down
19 changes: 15 additions & 4 deletions clif/pybind11/status_return_override.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@ namespace clif_pybind11 {

absl::Status StatusFromErrorAlreadySet(pybind11::error_already_set& e);

#if defined(PYBIND11_HAS_RETURN_VALUE_POLICY_PACK)
using rvp_or_rvpp = pybind11::return_value_policy_pack;
#define CLIF_PYBIND11_OVERLOAD_CALL_WITH_POLICIES(rvpp, argsddd) \
overload.call_with_policies(rvpp, argsddd)
#else
using rvp_or_rvpp = pybind11::return_value_policy;
#define CLIF_PYBIND11_OVERLOAD_CALL_WITH_POLICIES(rvpp, argsddd) \
overload(argsddd)
#endif

template<typename U>
pybind11::function GetOverload(
const U* this_ptr, const std::string& function_name) {
Expand All @@ -28,15 +38,16 @@ pybind11::function GetOverload(
template <typename U, typename... Ts>
absl::Status CatchErrorAlreadySetAndReturnStatus(
const U* this_ptr, const std::string& function_name,
const pybind11::return_value_policy_pack rvpp, Ts... args) {
const rvp_or_rvpp& rvpp, Ts... args) {
try {
pybind11::function overload = GetOverload(this_ptr, function_name);
if (!overload) {
return absl::Status(absl::StatusCode::kUnimplemented,
"No Python overload is defined for " + function_name +
".");
}
overload.call_with_policies(rvpp, args...); /* Ignoring return value. */
CLIF_PYBIND11_OVERLOAD_CALL_WITH_POLICIES(
rvpp, args...); /* Ignoring return value. */
return absl::OkStatus();
} catch (pybind11::error_already_set &e) {
return StatusFromErrorAlreadySet(e);
Expand All @@ -46,15 +57,15 @@ absl::Status CatchErrorAlreadySetAndReturnStatus(
template <typename StatusOrPayload, typename U, typename... Ts>
StatusOrPayload CatchErrorAlreadySetAndReturnStatusOr(
const U* this_ptr, const std::string& function_name,
const pybind11::return_value_policy_pack rvpp, Ts... args) {
const rvp_or_rvpp& rvpp, Ts... args) {
try {
pybind11::function overload = GetOverload(this_ptr, function_name);
if (!overload) {
return absl::Status(absl::StatusCode::kUnimplemented,
"No Python overload is defined for " + function_name +
".");
}
auto o = overload.call_with_policies(rvpp, args...);
auto o = CLIF_PYBIND11_OVERLOAD_CALL_WITH_POLICIES(rvpp, args...);
return o.template cast<StatusOrPayload>();
} catch (pybind11::error_already_set &e) {
return StatusFromErrorAlreadySet(e);
Expand Down

0 comments on commit 172f312

Please sign in to comment.