zeroSteiner / rule-engine

A lightweight, optionally typed expression language with a custom grammar for matching arbitrary Python objects.
https://zerosteiner.github.io/rule-engine/
BSD 3-Clause "New" or "Revised" License
445 stars 54 forks source link

Arithmetic comparison with None/null types #13

Closed aaditya-panik closed 3 years ago

aaditya-panik commented 3 years ago

Hi @zeroSteiner,

I had a question regarding how I can handle cases in which there are arithmetic comparisons (Or more generally speaking, any operations) with NoneTypes. For example, what is the expected behaviour here

rule_engine.Rule('a > 10').matches({'a': None})

This results in an exception

rule_engine.errors.EvaluationError: data type mismatch

but I was wondering if there is a way of suppressing that and evaluating it to False.

BTW, great project and looking forward to future features especially support for sets, kudos! :+1:

zeroSteiner commented 3 years ago

You could use the ternary operator, which I'm realizing now isn't particularly well documented. That would make this Rule('(a == null ? 0 : a) > 10').matches({'a': None}). You could also check that it's not null before doing the arithmetic comparison like Rule('a != null and a > 10').matches({'a': None}).

That's a little bit clunky though. My suggestion to make it easier for your rule writers is to normalize a in Python prior to evaluating the rule like rule_engine.Rule('a > 10').matches({'a': a or 0}).

aaditya-panik commented 3 years ago

Got it, thanks. I was hoping there was a way to evaluate expressions even if there was a type mismatch. I guess even if there would be, it would nullify the expression which is as good as handling the exception and evaluating the expression to None.