operators/today: fix corner cases yielding naive stamps
3 files changed, 20 insertions(+), 16 deletions(-)

M test/test_operator.py
M tshistory_formula/funcs.py
M tshistory_formula/interpreter.py
M test/test_operator.py +4 -2
@@ 1469,5 1469,7 @@ 2020-02-01 00:00:00+00:00  2020-01-01 00
         '(constant 3. (date "2020-1-1") (today) "D" (date "2020-2-1"))'
     )
 
-    with pytest.raises(AssertionError):
-        ts = tsh.get(engine, 'constant-3', revision_date=dt(2020, 2, 1))
+    # no crash wrt naive revision_date
+    tsh.get(engine, 'constant-3', revision_date=dt(2020, 2, 1))
+    tsh.get(engine, 'constant-3', from_value_date=dt(2020, 2, 1))
+    tsh.get(engine, 'constant-3', to_value_date=dt(2020, 2, 1))

          
M tshistory_formula/funcs.py +13 -10
@@ 209,12 209,15 @@ def today(__interpreter__,
     """
     Produces a timezone-aware timestamp as of today
 
-    The `tz` keyword allows to specify an alternate time zone.
     The `naive` keyword forces production of a naive timestamp.
+    The `tz` keyword allows to specify an alternate time zone
+    (if unpecified and not naive).
     Both `tz` and `naive` keywords are mutually exlcusive.
 
     Example: `(today)`
     """
+    # impl. note: if not naive and tz is none,
+    # tz will be utc
     return __interpreter__.today(naive, tz)
 
 

          
@@ 269,17 272,17 @@ def constant(__interpreter__,
 
 def _constant(__interpreter__, value, fromdate, todate, freq, revdate):
     getargs = __interpreter__.getargs
-    if getargs.get('revision_date'):
-        if getargs['revision_date'] < revdate:
-            return empty_series(True)
+    qrevdate = getargs.get('revision_date')
+    if qrevdate and ensuretz(qrevdate) < revdate:
+        return empty_series(True)
 
-    if getargs.get('from_insertion_date'):
-        if getargs['from_insertion_date'] > revdate:
-            return empty_series(True)
+    qfromidate = getargs.get('from_insertion_date')
+    if qfromidate and ensuretz(qfromidate) > revdate:
+        return empty_series(True)
 
-    if getargs.get('to_insertion_date'):
-        if getargs['to_insertion_date'] < revdate:
-            return empty_series(True)
+    qtoidate = getargs.get('to_insertion_date')
+    if qtoidate and ensuretz(qtoidate) < revdate:
+        return empty_series(True)
 
     mindate = getargs.get('from_value_date')
     if mindate:

          
M tshistory_formula/interpreter.py +3 -4
@@ 73,15 73,14 @@ class Interpreter:
     def today(self, naive, tz):
         if naive:
             assert tz is None, f'date cannot be naive and have a tz'
-        if tz:
-            tz = pytz.timezone(tz)
+        tz = pytz.timezone(tz or 'utc')
 
         key = ('today', naive, tz)
         if self.getargs.get('revision_date'):
             val = self.getargs['revision_date']
             if naive:
                val = val.replace(tzinfo=None)
-            if tz:
+            elif val.tzinfo is None:
                 val = pd.Timestamp(val, tz=tz)
             self.vcache[key] = val
             return val

          
@@ 93,7 92,7 @@ class Interpreter:
         if naive:
             val = pd.Timestamp(datetime.today())
         else:
-            val = pd.Timestamp(datetime.today(), tz=tz or 'utc')
+            val = pd.Timestamp(datetime.today(), tz=tz)
 
         self.vcache[key] = val
         return val