Skip to content

Commit 683cbea

Browse files
committed
Set the timezone for in GetItem and GetAttribute
1 parent 16e7a4c commit 683cbea

File tree

2 files changed

+20
-6
lines changed

2 files changed

+20
-6
lines changed

lib/rule_engine/ast.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,13 @@ class ExpressionBase(ASTNodeBase):
125125
def __repr__(self):
126126
return "<{0} >".format(self.__class__.__name__)
127127

128+
def _new_value(self, *args, **kwargs):
129+
# perform a context aware load of value
130+
value = coerce_value(*args, **kwargs)
131+
if isinstance(value, datetime.datetime) and value.tzinfo is None:
132+
value = value.replace(tzinfo=self.context.default_timezone)
133+
return value
134+
128135
class LiteralExpressionBase(ExpressionBase):
129136
"""A base class for representing literal values from the grammar text."""
130137
__slots__ = ('value',)
@@ -678,7 +685,7 @@ def evaluate(self, thing):
678685
except errors.AttributeResolutionError as error:
679686
attribute_error = error
680687
else:
681-
return coerce_value(value, verify_type=False)
688+
return self._new_value(value, verify_type=False)
682689

683690
try:
684691
value = self.context.resolve(resolved_obj, self.name)
@@ -692,7 +699,7 @@ def evaluate(self, thing):
692699
attribute_error.suggestion = suggestion
693700
raise attribute_error from None
694701
value = default_value
695-
return coerce_value(value, verify_type=False)
702+
return self._new_value(value, verify_type=False)
696703

697704
def reduce(self):
698705
if not _is_reduced(self.object):
@@ -766,7 +773,7 @@ def evaluate(self, thing):
766773
if self.safe:
767774
return None
768775
raise errors.LookupError(resolved_obj, resolved_item)
769-
return coerce_value(value, verify_type=False)
776+
return self._new_value(value, verify_type=False)
770777

771778
def reduce(self):
772779
if isinstance(self.container.result_type, DataType.MAPPING.__class__):
@@ -891,9 +898,7 @@ def evaluate(self, thing):
891898
if default_value is errors.UNDEFINED:
892899
raise
893900
value = default_value
894-
value = coerce_value(value, verify_type=False)
895-
if isinstance(value, datetime.datetime) and value.tzinfo is None:
896-
value = value.replace(tzinfo=self.context.default_timezone)
901+
value = self._new_value(value, verify_type=False)
897902

898903
# if the expected result type is undefined, return the value
899904
if self.result_type == DataType.UNDEFINED:

tests/issues.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3131
#
3232

33+
import datetime
3334
import random
3435
import unittest
3536

@@ -76,3 +77,11 @@ def test_number_19(self):
7677
def test_number_20(self):
7778
rule = engine.Rule('a / b ** 2')
7879
self.assertEqual(rule.evaluate({'a': 8, 'b': 4}), 0.5)
80+
81+
def test_number_22(self):
82+
rules = ('object["timestamp"] > $now', 'object.timestamp > $now')
83+
for rule in rules:
84+
rule = engine.Rule(rule)
85+
self.assertFalse(rule.evaluate({
86+
'object': {'timestamp': datetime.datetime(2021, 8, 19)}
87+
}))

0 commit comments

Comments
 (0)