From bc23cd08acaed0e881eb63db7a1b037d3d6883e7 Mon Sep 17 00:00:00 2001 From: Paulo Lieuthier Date: Fri, 27 Feb 2026 18:55:28 -0300 Subject: [PATCH] Python: boolean mapping (#612) * fix(python): boolean and integer mapping --- bindings/python/src/lib.rs | 21 +++++++++++++-------- bindings/python/test.py | 26 ++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/bindings/python/src/lib.rs b/bindings/python/src/lib.rs index 858c902..0e327d3 100644 --- a/bindings/python/src/lib.rs +++ b/bindings/python/src/lib.rs @@ -85,6 +85,10 @@ fn from(ob: &Bound<'_, PyAny>) -> Result { else if let Ok(s) = ob.extract::() { s.into() } + // Boolean + else if let Ok(b) = ob.extract::() { + b.into() + } // Numeric else if let Ok(v) = ob.extract::() { v.into() @@ -93,10 +97,6 @@ fn from(ob: &Bound<'_, PyAny>) -> Result { } else if let Ok(v) = ob.extract::() { v.into() } - // Boolean - else if let Ok(b) = ob.extract::() { - b.into() - } // None else if ob.downcast::().is_ok() { Value::Null @@ -138,12 +138,17 @@ fn to(mut v: Value, py: Python<'_>) -> Result { Value::String(s) => s.into_bound_py_any(py), Value::Number(_) => { - if let Ok(f) = v.as_f64() { + if v.as_number()?.is_integer() { + if let Ok(u) = v.as_u64() { + u.into_bound_py_any(py) + } else { + v.as_i64()?.into_bound_py_any(py) + } + } else if let Ok(f) = v.as_f64() { f.into_bound_py_any(py) - } else if let Ok(u) = v.as_u64() { - u.into_bound_py_any(py) } else { - v.as_i64()?.into_bound_py_any(py) + // fallback + v.as_f64()?.into_bound_py_any(py) } } diff --git a/bindings/python/test.py b/bindings/python/test.py index f1b56a7..aef2e18 100644 --- a/bindings/python/test.py +++ b/bindings/python/test.py @@ -387,3 +387,29 @@ def test_extension_types(): assert st == {10, 12}, f"Unexpected set: {st}" test_extension_types() + +def test_boolean_mapping(): + rego = regorus.Engine() + rego.add_policy("demo", + """ + package demo + + result_b := data.a if { + data.a == true + } + + result_i := data.b if { + data.b == 1 + } + """) + rego.add_data({"a": True, "b": 1}) + + result_b = rego.eval_rule("data.demo.result_b") + assert isinstance(result_b, bool), f"Expected bool, got {type(result_b)}" + assert result_b, f"Unexpected result for 'result_b': {result_b}" + + result_i = rego.eval_rule("data.demo.result_i") + assert isinstance(result_i, int), f"Expected int, got {type(result_i)}" + assert result_i == 1, f"Unexpected result for 'result_i': {result_i}" + +test_boolean_mapping()