Variable memoization seems broken on Python 3.4.1
Closed this issue · 3 comments
The function memoization seems to be broken on Python 3.4.1. I've got the
following variables and rules for a Django model called Entry
(just assume
it's got some text and a submitted_on
field that is a datetime
object).
The variables are configured like so:
class EntryVariables(BaseVariables):
def __init__(self, entry):
self.entry = entry
@string_rule_variable
def submitted_day(self):
# Weekday as locale’s full name; e.g. 'Saturday'
return self.entry.submitted_on.strftime("%A")
While the Actions are configured as:
class EntryActions(BaseActions):
def __init__(self, entry):
self.entry = entry
@rule_action(params={}) # Seems I need params or this doesn't work?
def send_notification(self):
print("Have a great Weekend")
I've got the following rules:
entry_rules = [
{
"conditions": {
"all": [
{
"name": "submitted_day",
"operator": "equal_to",
"value": "Saturday",
},
]
},
"actions": [
{
"name": "send_notification",
"fields": [],
},
],
},
]
And I'm running the rules like so:
# Running all the rules
def run_rules():
for entry in Entry.objects.all(): # Gives me all Entry instances.
run_all(
rule_list=entry_rules,
defined_variables=EntryVariables(entry),
defined_actions=EntryActions(entry),
stop_on_first_trigger=False
)
As configured above, doing this results in:
.../business_rules/engine.py in _get_variable_value(defined_variables, name)
67 method = getattr(defined_variables, name, fallback)
68 val = method()
---> 69 return method.field_type(val)
70
71 def _do_operator_comparison(operator_type, operator_name, comparison_value):
AttributeError: 'function' object has no attribute 'field_type'
However, if I skip the memoization of the variables, by using the rule_variable
decorator directly, things work as expected.
class EntryVariables(BaseVariables):
# ...
@rule_variable(StringType, cache_result=False) # Don't cache.
def submitted_day(self):
# ...
Meanwhile, at the point in the stack trace above, method
appears to be:
<bound method EntryVariables.wrapper of <myapp.rules.EntryVariables object at 0x104834208>>
which does not have a field_type
attribute, while val
is:
<function _memoize_return_values.<locals>.memf at 0x10486bd08>
and does seem to have the field_type
attribute, and also seems to be an
instance of a rule variable (val.is_rule_variable
is True
).
I'm a little at a loss as to what the intention was here, but I wanted to report
what I've found so far.
Any ideas? Am I doing something obviously wrong?
Thanks in advance!
@bradmontgomery try defining your submitted_day
variable like this:
@string_rule_variable()
def submitted_day(self):
# Weekday as locale’s full name; e.g. 'Saturday'
return self.entry.submitted_on.strftime("%A")
Notice the open/close parens on the decorator. This should fix the issue.
@bradmontgomery this PR should fix that requirement: #17
doh! Thanks for the clarification 😅
And 👍 for #17