mirror of
https://github.com/microsoft/regorus.git
synced 2026-08-05 02:16:11 +00:00
Fix bindings and add CI tests (#247)
Also update version numbers of binding Rust projects to match Regorus Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
This commit is contained in:
committed by
GitHub
parent
495e91c75a
commit
9894f00829
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "regoruspy"
|
||||
version = "0.1.0"
|
||||
version = "0.1.5"
|
||||
edition = "2021"
|
||||
repository = "https://github.com/microsoft/regorus/bindings/python"
|
||||
description = "Python bindings for Regorus - a fast, lightweight Rego interpreter written in Rust"
|
||||
|
||||
@@ -33,12 +33,12 @@ impl Clone for Engine {
|
||||
}
|
||||
}
|
||||
|
||||
fn from<'source>(ob: &'source PyAny) -> Result<Value, PyErr> {
|
||||
fn from<'source>(ob: &Bound<'_, PyAny>) -> Result<Value, PyErr> {
|
||||
// dicts
|
||||
Ok(if let Ok(dict) = ob.downcast::<PyDict>() {
|
||||
let mut map = BTreeMap::new();
|
||||
for (k, v) in dict {
|
||||
map.insert(from(k)?, from(v)?);
|
||||
map.insert(from(&k)?, from(&v)?);
|
||||
}
|
||||
map.into()
|
||||
}
|
||||
@@ -46,7 +46,7 @@ fn from<'source>(ob: &'source PyAny) -> Result<Value, PyErr> {
|
||||
else if let Ok(pset) = ob.downcast::<PySet>() {
|
||||
let mut set = BTreeSet::new();
|
||||
for v in pset {
|
||||
set.insert(from(v)?);
|
||||
set.insert(from(&v)?);
|
||||
}
|
||||
set.into()
|
||||
}
|
||||
@@ -55,7 +55,7 @@ fn from<'source>(ob: &'source PyAny) -> Result<Value, PyErr> {
|
||||
//
|
||||
let mut set = BTreeSet::new();
|
||||
for v in pfset {
|
||||
set.insert(from(v)?);
|
||||
set.insert(from(&v)?);
|
||||
}
|
||||
set.into()
|
||||
}
|
||||
@@ -63,30 +63,30 @@ fn from<'source>(ob: &'source PyAny) -> Result<Value, PyErr> {
|
||||
else if let Ok(plist) = ob.downcast::<PyList>() {
|
||||
let mut array = Vec::new();
|
||||
for v in plist {
|
||||
array.push(from(v)?);
|
||||
array.push(from(&v)?);
|
||||
}
|
||||
array.into()
|
||||
} else if let Ok(ptuple) = ob.downcast::<PyTuple>() {
|
||||
let mut array = Vec::new();
|
||||
for v in ptuple {
|
||||
array.push(from(v)?);
|
||||
array.push(from(&v)?);
|
||||
}
|
||||
array.into()
|
||||
}
|
||||
// String
|
||||
else if let Ok(s) = String::extract(ob) {
|
||||
else if let Ok(s) = ob.extract::<String>() {
|
||||
s.into()
|
||||
}
|
||||
// Numeric
|
||||
else if let Ok(v) = i64::extract(ob) {
|
||||
else if let Ok(v) = ob.extract::<i64>() {
|
||||
v.into()
|
||||
} else if let Ok(v) = u64::extract(ob) {
|
||||
} else if let Ok(v) = ob.extract::<u64>() {
|
||||
v.into()
|
||||
} else if let Ok(v) = f64::extract(ob) {
|
||||
} else if let Ok(v) = ob.extract::<f64>() {
|
||||
v.into()
|
||||
}
|
||||
// Boolean
|
||||
else if let Ok(b) = bool::extract(ob) {
|
||||
else if let Ok(b) = ob.extract::<bool>() {
|
||||
b.into()
|
||||
}
|
||||
// None
|
||||
@@ -97,7 +97,7 @@ fn from<'source>(ob: &'source PyAny) -> Result<Value, PyErr> {
|
||||
else if let Ok(pseq) = ob.downcast::<PySequence>() {
|
||||
let mut array = Vec::new();
|
||||
for i in 0..pseq.len()? {
|
||||
array.push(from(pseq.get_item(i)?)?);
|
||||
array.push(from(&pseq.get_item(i)?)?);
|
||||
}
|
||||
array.into()
|
||||
}
|
||||
@@ -109,7 +109,7 @@ fn from<'source>(ob: &'source PyAny) -> Result<Value, PyErr> {
|
||||
for i in 0..keys.len()? {
|
||||
let key = keys.get_item(i)?;
|
||||
let value = values.get_item(i)?;
|
||||
map.insert(from(key)?, from(value)?);
|
||||
map.insert(from(&key)?, from(&value)?);
|
||||
}
|
||||
map.into()
|
||||
} else {
|
||||
@@ -140,7 +140,7 @@ fn to(mut v: Value, py: Python<'_>) -> Result<PyObject> {
|
||||
}
|
||||
|
||||
Value::Array(_) => {
|
||||
let list = PyList::empty(py);
|
||||
let list = PyList::empty_bound(py);
|
||||
for v in std::mem::replace(v.as_array_mut()?, Vec::new()) {
|
||||
list.append(to(v, py)?)?;
|
||||
}
|
||||
@@ -148,7 +148,7 @@ fn to(mut v: Value, py: Python<'_>) -> Result<PyObject> {
|
||||
}
|
||||
|
||||
Value::Set(_) => {
|
||||
let set = PySet::empty(py)?;
|
||||
let set = PySet::empty_bound(py)?;
|
||||
for v in std::mem::replace(v.as_set_mut()?, BTreeSet::new()) {
|
||||
set.add(to(v, py)?)?;
|
||||
}
|
||||
@@ -156,7 +156,7 @@ fn to(mut v: Value, py: Python<'_>) -> Result<PyObject> {
|
||||
}
|
||||
|
||||
Value::Object(_) => {
|
||||
let dict = PyDict::new(py);
|
||||
let dict = PyDict::new_bound(py);
|
||||
for (k, v) in std::mem::replace(v.as_object_mut()?, BTreeMap::new()) {
|
||||
dict.set_item(to(k, py)?, to(v, py)?)?;
|
||||
}
|
||||
@@ -181,7 +181,7 @@ impl Engine {
|
||||
///
|
||||
/// * `path`: A filename to be associated with the policy.
|
||||
/// * `rego`: Rego policy.
|
||||
pub fn add_policy(&mut self, path: String, rego: String) -> Result<()> {
|
||||
pub fn add_policy(&mut self, path: String, rego: String) -> Result<String> {
|
||||
self.engine.add_policy(path, rego)
|
||||
}
|
||||
|
||||
@@ -190,15 +190,21 @@ impl Engine {
|
||||
/// The policy is parsed into AST.
|
||||
///
|
||||
/// * `path`: Path to the policy file.
|
||||
pub fn add_policy_from_file(&mut self, path: String) -> Result<()> {
|
||||
pub fn add_policy_from_file(&mut self, path: String) -> Result<String> {
|
||||
self.engine.add_policy_from_file(path)
|
||||
}
|
||||
|
||||
/// Get the list of packages defined by loaded policies.
|
||||
///
|
||||
pub fn get_packages(&mut self) -> Result<Vec<String>> {
|
||||
self.engine.get_packages()
|
||||
}
|
||||
|
||||
/// Add policy data.
|
||||
///
|
||||
/// * `data`: Rego value. A Rego value is a number, bool, string, None
|
||||
/// or a list/set/map whose items themselves are Rego values.
|
||||
pub fn add_data(&mut self, data: &PyAny) -> Result<()> {
|
||||
pub fn add_data(&mut self, data: &Bound<'_, PyAny>) -> Result<()> {
|
||||
let data = from(data)?;
|
||||
self.engine.add_data(data)
|
||||
}
|
||||
@@ -229,7 +235,7 @@ impl Engine {
|
||||
///
|
||||
/// * `input`: Rego value. A Rego value is a number, bool, string, None
|
||||
/// or a list/set/map whose items themselves are Rego values.
|
||||
pub fn set_input(&mut self, input: &PyAny) -> Result<()> {
|
||||
pub fn set_input(&mut self, input: &Bound<'_, PyAny>) -> Result<()> {
|
||||
let input = from(input)?;
|
||||
self.engine.set_input(input);
|
||||
Ok(())
|
||||
@@ -259,17 +265,17 @@ impl Engine {
|
||||
pub fn eval_query(&mut self, query: String, py: Python<'_>) -> Result<PyObject> {
|
||||
let results = self.engine.eval_query(query, false)?;
|
||||
|
||||
let rlist = PyList::empty(py);
|
||||
let rlist = PyList::empty_bound(py);
|
||||
for result in results.result.into_iter() {
|
||||
let rdict = PyDict::new(py);
|
||||
let rdict = PyDict::new_bound(py);
|
||||
|
||||
let elist = PyList::empty(py);
|
||||
let elist = PyList::empty_bound(py);
|
||||
for expr in result.expressions.into_iter() {
|
||||
let edict = PyDict::new(py);
|
||||
let edict = PyDict::new_bound(py);
|
||||
edict.set_item("value".to_object(py), to(expr.value, py)?)?;
|
||||
edict.set_item("text".to_object(py), expr.text.as_ref().to_object(py))?;
|
||||
|
||||
let ldict = PyDict::new(py);
|
||||
let ldict = PyDict::new_bound(py);
|
||||
ldict.set_item("row".to_object(py), expr.location.row.to_object(py))?;
|
||||
ldict.set_item("col".to_object(py), expr.location.col.to_object(py))?;
|
||||
|
||||
@@ -281,7 +287,7 @@ impl Engine {
|
||||
rdict.set_item("bindings".to_object(py), to(result.bindings, py)?)?;
|
||||
rlist.append(rdict)?;
|
||||
}
|
||||
let dict = PyDict::new(py);
|
||||
let dict = PyDict::new_bound(py);
|
||||
dict.set_item("result".to_object(py), rlist)?;
|
||||
Ok(dict.into())
|
||||
}
|
||||
@@ -296,6 +302,6 @@ impl Engine {
|
||||
}
|
||||
|
||||
#[pymodule]
|
||||
pub fn regorus(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
|
||||
pub fn regorus(_py: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> {
|
||||
m.add_class::<crate::Engine>()
|
||||
}
|
||||
|
||||
@@ -7,9 +7,14 @@ import regorus
|
||||
engine = regorus.Engine()
|
||||
|
||||
# Load policies
|
||||
engine.add_policy_from_file('../../tests/aci/framework.rego')
|
||||
engine.add_policy_from_file('../../tests/aci/api.rego')
|
||||
engine.add_policy_from_file('../../tests/aci/policy.rego')
|
||||
pkg = engine.add_policy_from_file('../../tests/aci/framework.rego')
|
||||
print(' Loaded Policy %s' % pkg)
|
||||
|
||||
pkg = engine.add_policy_from_file('../../tests/aci/api.rego')
|
||||
print(' Loaded Policy %s' % pkg)
|
||||
|
||||
pkg = engine.add_policy_from_file('../../tests/aci/policy.rego')
|
||||
print(' Loaded Policy %s' % pkg)
|
||||
|
||||
# Add policy data
|
||||
data = {
|
||||
|
||||
Reference in New Issue
Block a user