Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Variable memoization seems broken on Python 3.4.1 #16

Closed
bradmontgomery opened this issue Dec 9, 2014 · 3 comments
Closed

Variable memoization seems broken on Python 3.4.1 #16

bradmontgomery opened this issue Dec 9, 2014 · 3 comments

Comments

@bradmontgomery
Copy link
Contributor

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!

@gregeinfrank
Copy link
Contributor

@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.

@gregeinfrank
Copy link
Contributor

@bradmontgomery this PR should fix that requirement: #17

@bradmontgomery
Copy link
Contributor Author

doh! Thanks for the clarification 😅

And 👍 for #17

vrsandeep pushed a commit to vrsandeep/business-rules that referenced this issue May 31, 2019
…sults

CP-455: Return a list of booleans from run_all
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants