Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,6 @@ pybind_extension(
"@com_google_cel_spec//proto/cel/expr:syntax_cc_proto",
"@com_google_protobuf//:protobuf",
"@pybind11_abseil//pybind11_abseil:absl_casters",
"@pybind11_abseil//pybind11_abseil:import_status_module",
"@pybind11_abseil//pybind11_abseil:status_casters",
],
)

Expand Down
14 changes: 6 additions & 8 deletions py_cel_env.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,14 @@
#include <vector>

#include "absl/log/absl_check.h"
#include "absl/status/statusor.h"
#include "py_cel_activation.h"
#include "py_cel_arena.h"
#include "py_cel_env_internal.h"
#include "py_cel_expression.h"
#include "py_cel_type.h"
#include "py_error_status.h"
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include "pybind11_abseil/status_casters.h"

namespace cel_python {

Expand Down Expand Up @@ -121,14 +120,13 @@ std::shared_ptr<PyCelActivation> PyCelEnv::NewActivation(
return std::make_shared<PyCelActivation>(env_, data, functions, arena);
}

absl::StatusOr<PyCelExpression> PyCelEnv::Compile(const std::string& cel_expr,
bool disable_check) {
return PyCelExpression::Compile(env_, cel_expr, disable_check);
PyCelExpression PyCelEnv::Compile(const std::string& cel_expr,
bool disable_check) {
return ThrowIfError(PyCelExpression::Compile(env_, cel_expr, disable_check));
}

absl::StatusOr<PyCelExpression> PyCelEnv::Deserialize(
const std::string& serialized_expr) {
return PyCelExpression::Deserialize(env_, serialized_expr);
PyCelExpression PyCelEnv::Deserialize(const std::string& serialized_expr) {
return ThrowIfError(PyCelExpression::Deserialize(env_, serialized_expr));
}

} // namespace cel_python
10 changes: 5 additions & 5 deletions py_cel_env.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
#include <unordered_map>
#include <vector>

#include "absl/status/statusor.h"
#include "py_cel_activation.h"
#include "py_cel_arena.h"
#include "py_cel_expression.h"
Expand Down Expand Up @@ -52,10 +51,11 @@ class PyCelEnv {

~PyCelEnv();

absl::StatusOr<PyCelExpression> Compile(const std::string& cel_expr,
bool disable_check = false);
absl::StatusOr<PyCelExpression> Deserialize(
const std::string& serialized_expr);
// May throw exceptions.
PyCelExpression Compile(const std::string& cel_expr,
bool disable_check = false);
// May throw exceptions.
PyCelExpression Deserialize(const std::string& serialized_expr);
std::shared_ptr<PyCelActivation> NewActivation(
const std::unordered_map<std::string, PyObject*>& data,
const std::vector<std::shared_ptr<PyCelFunction>>& functions,
Expand Down
14 changes: 6 additions & 8 deletions py_cel_expression.cc
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@
#include "status_macros.h"
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include "pybind11_abseil/status_casters.h"

namespace cel_python {

Expand All @@ -79,26 +78,25 @@ void PyCelExpression::DefinePythonBindings(py::module& m) {
data,
const std::optional<std::vector<std::shared_ptr<PyCelFunction>>>&
functions,
const std::shared_ptr<PyCelArena>& arena =
nullptr) -> absl::StatusOr<PyCelValue> {
const std::shared_ptr<PyCelArena>& arena = nullptr) -> PyCelValue {
if (activation) {
if (data || functions || arena) {
return absl::InvalidArgumentError(
"Cannot provide both activation and any other arguments.");
throw StatusToException(absl::InvalidArgumentError(
"Cannot provide both activation and any other arguments."));
}
return self.Eval(**activation);
return ThrowIfError(self.Eval(**activation));
}
std::unordered_map<std::string, PyObject*> data_ptrs;
if (data) {
for (auto const& [key, val] : *data) {
data_ptrs[key] = val.ptr();
}
}
return self.Eval(PyCelActivation(
return ThrowIfError(self.Eval(PyCelActivation(
self.env_, data_ptrs,
functions.value_or(
std::vector<std::shared_ptr<PyCelFunction>>{}),
arena ? arena : NewArena()));
arena ? arena : NewArena())));
},
py::arg("activation") = py::none(), py::arg("data") = py::none(),
py::arg("functions") = py::none(), py::arg("arena") = nullptr);
Expand Down
33 changes: 9 additions & 24 deletions py_cel_function.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
#include "status_macros.h"
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include "pybind11_abseil/status_casters.h"

namespace cel_python {

Expand All @@ -56,7 +55,7 @@ static std::shared_ptr<PyCelEnvInternal> GetEnvFromContext(

void PyCelFunction::DefinePythonBindings(pybind11::module& m) {
py::class_<PyCelFunction, std::shared_ptr<PyCelFunction>>(m, "Function")
.def(py::init<std::string, std::vector<PyCelType>, bool, PyObject*,
.def(py::init<std::string, std::vector<PyCelType>, bool, py::object,
PyCelType>(),
py::arg("function_name"), py::arg("parameters"),
py::arg("is_member"), py::arg("impl"),
Expand All @@ -65,36 +64,21 @@ void PyCelFunction::DefinePythonBindings(pybind11::module& m) {

PyCelFunction::PyCelFunction(std::string function_name,
std::vector<PyCelType> parameters, bool is_member,
PyObject* impl, PyCelType return_type)
py::object impl, PyCelType return_type)
: function_name_(std::move(function_name)),
return_type_(std::move(return_type)),
parameters_(std::move(parameters)),
is_member_(is_member),
impl_(impl) {
impl_(std::move(impl)) {
ABSL_CHECK(PyGILState_Check());
Py_XINCREF(impl_);
}

PyCelFunction::~PyCelFunction() {
auto gil_state = PyGILState_Ensure();
Py_XDECREF(impl_);
PyGILState_Release(gil_state);
};

PyCelFunctionAdapter::PyCelFunctionAdapter(std::string function_name,
PyCelType return_type,
PyObject* py_function)
py::object py_function)
: function_name_(std::move(function_name)),
return_type_(std::move(return_type)),
py_function_(py_function) {
Py_XINCREF(py_function_);
}

PyCelFunctionAdapter::~PyCelFunctionAdapter() {
auto gil_state = PyGILState_Ensure();
Py_XDECREF(py_function_);
PyGILState_Release(gil_state);
}
py_function_(std::move(py_function)) {}

absl::StatusOr<cel::Value> PyCelFunctionAdapter::Invoke(
absl::Span<const cel::Value> args,
Expand All @@ -110,7 +94,7 @@ absl::StatusOr<cel::Value> PyCelFunctionAdapter::Invoke(
CelValueToPyObject(args[i], env, py_arena,
/*plain_value=*/true));
}
PyObject* result = PyObject_CallObject(py_function_, py_args);
PyObject* result = PyObject_CallObject(py_function_.ptr(), py_args);
absl::Status status = PyErr_toStatus();
if (!status.ok()) {
return cel::ErrorValue(status);
Expand All @@ -119,8 +103,9 @@ absl::StatusOr<cel::Value> PyCelFunctionAdapter::Invoke(
return PyObjectToCelValue(
result, return_type_,
[this]() {
return absl::StrFormat("Python function '%s'",
PyUnicode_AsUTF8(PyObject_Repr(py_function_)));
return absl::StrFormat(
"Python function '%s'",
PyUnicode_AsUTF8(PyObject_Repr(py_function_.ptr())));
},
env, context.arena());
};
Expand Down
14 changes: 7 additions & 7 deletions py_cel_function.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@

namespace cel_python {

namespace py = ::pybind11;

class PyCelEnvInternal;

// Wrapper for a Python function that implements a CEL late-bound function.
Expand All @@ -38,30 +40,28 @@ class PyCelFunction {
static void DefinePythonBindings(pybind11::module& m);

PyCelFunction(std::string function_name, std::vector<PyCelType> parameters,
bool is_member, PyObject* impl, PyCelType return_type);
~PyCelFunction();
bool is_member, py::object impl, PyCelType return_type);

std::string function_name() const { return function_name_; }
const std::vector<PyCelType>& parameters() const { return parameters_; }
bool is_member() const { return is_member_; }
PyObject* impl() const { return impl_; }
py::object impl() const { return impl_; }
const PyCelType& return_type() const { return return_type_; }

private:
std::string function_name_;
PyCelType return_type_;
std::vector<PyCelType> parameters_;
bool is_member_;
PyObject* impl_;
py::object impl_;
};

// Internal wrapper for a Python function that implements a CEL extension
// function.
class PyCelFunctionAdapter : public cel::Function {
public:
PyCelFunctionAdapter(std::string function_name, PyCelType return_type,
PyObject* py_function);
~PyCelFunctionAdapter() override;
py::object py_function);

absl::StatusOr<cel::Value> Invoke(
absl::Span<const cel::Value> args,
Expand All @@ -70,7 +70,7 @@ class PyCelFunctionAdapter : public cel::Function {
private:
std::string function_name_;
PyCelType return_type_;
PyObject* py_function_;
py::object py_function_;
};

} // namespace cel_python
Expand Down
2 changes: 0 additions & 2 deletions py_cel_function_decl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
#include "py_cel_overload.h"
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include "pybind11_abseil/absl_casters.h"
#include "pybind11_abseil/status_casters.h"

namespace cel_python {

Expand Down
2 changes: 0 additions & 2 deletions py_cel_module.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,10 @@
#include "py_cel_type.h"
#include "py_cel_value.h"
#include <pybind11/pybind11.h>
#include "pybind11_abseil/import_status_module.h"

namespace cel_python {

PYBIND11_MODULE(py_cel, m) {
pybind11::google::ImportStatusModule();
m.doc() = "Python bindings for CEL.";

PyCelArena::DefinePythonBindings(m);
Expand Down
38 changes: 5 additions & 33 deletions py_cel_overload.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
#include "py_cel_type.h"
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include "pybind11_abseil/status_casters.h"

namespace cel_python {

Expand All @@ -33,50 +32,23 @@ void PyCelOverload::DefinePythonBindings(py::module_& m) {
.def(py::init([](const std::string& overload_id,
const PyCelType& return_type,
const std::vector<PyCelType>& parameters, bool is_member,
PyObject* impl) {
py::object impl) {
return PyCelOverload(overload_id, return_type, parameters,
is_member, impl != Py_None ? impl : nullptr);
is_member, std::move(impl));
}),
py::arg("overload_id"), py::arg("return_type"),
py::arg("parameters"), py::arg("is_member") = false,
py::arg("impl") = nullptr);
py::arg("impl") = py::none());
}

PyCelOverload::PyCelOverload(std::string overload_id,
const PyCelType& return_type,
std::vector<PyCelType> parameters, bool is_member,
PyObject* py_function)
py::object py_function)
: overload_id_(std::move(overload_id)),
return_type_(return_type),
parameters_(std::move(parameters)),
is_member_(is_member),
py_function_(py_function) {
Py_XINCREF(py_function_);
}

PyCelOverload::PyCelOverload(const PyCelOverload& other) {
overload_id_ = other.overload_id_;
return_type_ = other.return_type_;
parameters_ = other.parameters_;
is_member_ = other.is_member_;
py_function_ = other.py_function_;
Py_XINCREF(py_function_);
};

PyCelOverload& PyCelOverload::operator=(const PyCelOverload& other) {
overload_id_ = other.overload_id_;
return_type_ = other.return_type_;
parameters_ = other.parameters_;
is_member_ = other.is_member_;
py_function_ = other.py_function_;
Py_XINCREF(py_function_);
return *this;
}

PyCelOverload::~PyCelOverload() {
auto gil_state = PyGILState_Ensure();
Py_XDECREF(py_function_);
PyGILState_Release(gil_state);
}
py_function_(std::move(py_function)) {}

} // namespace cel_python
13 changes: 7 additions & 6 deletions py_cel_overload.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,30 +25,31 @@

namespace cel_python {

namespace py = ::pybind11;

class PyCelOverload {
public:
static void DefinePythonBindings(pybind11::module& m);

PyCelOverload(const PyCelOverload&);
PyCelOverload& operator=(const PyCelOverload&);
PyCelOverload(const PyCelOverload&) = default;
PyCelOverload& operator=(const PyCelOverload&) = default;

PyCelOverload(std::string overload_id, const PyCelType& return_type,
std::vector<PyCelType> parameters, bool is_member = false,
PyObject* py_function = nullptr);
~PyCelOverload();
py::object py_function = py::none());

std::string overload_id() const { return overload_id_; }
PyCelType return_type() const { return return_type_; }
const std::vector<PyCelType>& parameters() const { return parameters_; }
bool is_member() const { return is_member_; }
PyObject* py_function() const { return py_function_; }
py::object py_function() const { return py_function_; }

private:
std::string overload_id_;
PyCelType return_type_;
std::vector<PyCelType> parameters_;
bool is_member_;
PyObject* py_function_ = nullptr;
py::object py_function_ = py::none();
};

} // namespace cel_python
Expand Down
2 changes: 1 addition & 1 deletion py_cel_python_extension.cc
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ absl::Status PyCelPythonExtension::ConfigureRuntime(

cel::FunctionDescriptor descriptor(function.name(), overload.is_member(),
types, kFunctionDescriptorOptions);
if (overload.py_function()) {
if (!overload.py_function().is_none()) {
PY_CEL_RETURN_IF_ERROR(runtime_builder.function_registry().Register(
descriptor, std::make_unique<PyCelFunctionAdapter>(
function.name(), overload.return_type(),
Expand Down
Loading