-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Major status_casters.h internal refactoring.
PiperOrigin-RevId: 426017387
- Loading branch information
1 parent
9490b25
commit 1bb411e
Showing
11 changed files
with
329 additions
and
208 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
#include "pybind11_abseil/import_status_module.h" | ||
|
||
#include <pybind11/pybind11.h> | ||
|
||
#include "absl/status/status.h" | ||
#include "pybind11_abseil/check_status_module_imported.h" | ||
#include "pybind11_abseil/register_status_bindings.h" | ||
|
||
namespace pybind11 { | ||
namespace google { | ||
|
||
module ImportStatusModule(bool bypass_regular_import) { | ||
if (!PyGILState_Check()) { | ||
pybind11_fail("ImportStatusModule() PyGILState_Check() failure."); | ||
} | ||
if (bypass_regular_import) { | ||
auto m = reinterpret_borrow<module>(PyImport_AddModule( | ||
PYBIND11_TOSTRING(PYBIND11_ABSEIL_STATUS_MODULE_PATH))); | ||
if (!internal::IsStatusModuleImported()) { | ||
internal::RegisterStatusBindings(m); | ||
} | ||
// else no-op because bindings are already loaded. | ||
return m; | ||
} | ||
return module::import(PYBIND11_TOSTRING(PYBIND11_ABSEIL_STATUS_MODULE_PATH)); | ||
} | ||
|
||
} // namespace google | ||
} // namespace pybind11 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#ifndef PYBIND11_ABSEIL_IMPORT_STATUS_MODULE_H_ | ||
#define PYBIND11_ABSEIL_IMPORT_STATUS_MODULE_H_ | ||
|
||
#include <pybind11/pybind11.h> | ||
|
||
// The value of PYBIND11_ABSEIL_STATUS_MODULE_PATH will be different depending | ||
// on whether this is being used inside or outside of google3. The value used | ||
// inside of google3 is defined here. Outside of google3, change this value by | ||
// passing "-DPYBIND11_ABSEIL_STATUS_MODULE_PATH=..." on the commandline. | ||
#ifndef PYBIND11_ABSEIL_STATUS_MODULE_PATH | ||
#define PYBIND11_ABSEIL_STATUS_MODULE_PATH \ | ||
pybind11_abseil.status | ||
#endif | ||
|
||
namespace pybind11 { | ||
namespace google { | ||
|
||
// Imports the bindings for the status types. This is meant to only be called | ||
// from a PYBIND11_MODULE definition. The Python GIL must be held when calling | ||
// this function (enforced). | ||
module ImportStatusModule(bool bypass_regular_import = true); | ||
|
||
} // namespace google | ||
} // namespace pybind11 | ||
|
||
#endif // PYBIND11_ABSEIL_IMPORT_STATUS_MODULE_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#ifndef PYBIND11_ABSEIL_REGISTER_STATUS_BINDINGS_H_ | ||
#define PYBIND11_ABSEIL_REGISTER_STATUS_BINDINGS_H_ | ||
|
||
#include <pybind11/pybind11.h> | ||
|
||
namespace pybind11 { | ||
namespace google { | ||
namespace internal { | ||
|
||
// Registers the bindings for the status types in the given module. Can only | ||
// be called once; subsequent calls will fail due to duplicate registrations. | ||
void RegisterStatusBindings(module m); | ||
|
||
} // namespace internal | ||
} // namespace google | ||
} // namespace pybind11 | ||
|
||
#endif // PYBIND11_ABSEIL_REGISTER_STATUS_BINDINGS_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,11 @@ | ||
#include <pybind11/pybind11.h> | ||
|
||
#include "pybind11_abseil/status_utils.h" | ||
#include "pybind11_abseil/register_status_bindings.h" | ||
|
||
namespace pybind11 { | ||
namespace google { | ||
|
||
PYBIND11_MODULE(status, m) { RegisterStatusBindings(m); } | ||
PYBIND11_MODULE(status, m) { internal::RegisterStatusBindings(m); } | ||
|
||
} // namespace google | ||
} // namespace pybind11 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
// Author: Ken Oslund (kenoslund@) | ||
#ifndef PYBIND11_ABSEIL_STATUS_CASTER_H_ | ||
#define PYBIND11_ABSEIL_STATUS_CASTER_H_ | ||
|
||
#include <pybind11/pybind11.h> | ||
|
||
#include <stdexcept> | ||
#include <type_traits> | ||
#include <utility> | ||
|
||
#include "absl/status/status.h" | ||
#include "pybind11_abseil/check_status_module_imported.h" | ||
#include "pybind11_abseil/no_throw_status.h" | ||
#include "pybind11_abseil/status_not_ok_exception.h" | ||
|
||
namespace pybind11 { | ||
namespace detail { | ||
|
||
template <typename StatusType> | ||
struct NoThrowStatusType { | ||
// NoThrowStatus should only wrap absl::Status or absl::StatusOr. | ||
using NoThrowAbslStatus = type_caster_base<absl::Status>; | ||
static constexpr auto name = NoThrowAbslStatus::name; | ||
}; | ||
|
||
// Convert NoThrowStatus by dispatching to a caster for StatusType with the | ||
// argument throw_exception = false. StatusType should be an absl::Status | ||
// (rvalue, lvalue, reference, or pointer), or an absl::StatusOr value. | ||
// Only return values trigger exceptions, so NoThrowStatus has no meaning for | ||
// input values. Therefore only C++->Python casting is supported. | ||
template <typename StatusType> | ||
struct type_caster<google::NoThrowStatus<StatusType>> { | ||
using InputType = google::NoThrowStatus<StatusType>; | ||
using StatusCaster = make_caster<StatusType>; | ||
static constexpr auto name = NoThrowStatusType<StatusType>::name; | ||
|
||
// Convert C++->Python. | ||
static handle cast(const InputType& src, return_value_policy policy, | ||
handle parent) { | ||
// pybind11::cast applies a const qualifier, so this takes a const reference | ||
// argument. The qualifiers we care about are in StatusType, and we will | ||
// forward those, but to do so, we must strip the const off the InputType. | ||
return StatusCaster::cast( | ||
std::forward<StatusType>(const_cast<InputType&>(src).status), policy, | ||
parent, false); | ||
} | ||
}; | ||
|
||
// Convert absl::Status. | ||
template <> | ||
struct type_caster<absl::Status> : public type_caster_base<absl::Status> { | ||
public: | ||
static constexpr auto name = _("None"); | ||
// Convert C++ -> Python. | ||
static handle cast(const absl::Status* src, return_value_policy policy, | ||
handle parent, bool throw_exception = true) { | ||
if (!src) return none().release(); | ||
return cast_impl(*src, policy, parent, throw_exception); | ||
} | ||
|
||
static handle cast(const absl::Status& src, return_value_policy policy, | ||
handle parent, bool throw_exception = true) { | ||
return cast_impl(src, policy, parent, throw_exception); | ||
} | ||
|
||
static handle cast(absl::Status&& src, return_value_policy policy, | ||
handle parent, bool throw_exception = true) { | ||
return cast_impl(std::move(src), policy, parent, throw_exception); | ||
} | ||
|
||
private: | ||
template <typename CType> | ||
static handle cast_impl(CType&& src, return_value_policy policy, | ||
handle parent, bool throw_exception) { | ||
google::internal::CheckStatusModuleImported(); | ||
if (!throw_exception) { | ||
// Use the built-in/standard pybind11 caster. | ||
return type_caster_base<absl::Status>::cast(std::forward<CType>(src), | ||
policy, parent); | ||
} else if (!src.ok()) { | ||
// Convert a non-ok status into an exception. | ||
throw google::StatusNotOk(std::forward<CType>(src)); | ||
} else { | ||
// Return none for an ok status. | ||
return none().release(); | ||
} | ||
} | ||
}; | ||
|
||
} // namespace detail | ||
} // namespace pybind11 | ||
|
||
#endif // PYBIND11_ABSEIL_STATUS_CASTER_H_ |
Oops, something went wrong.