Various changes.
[python_utils.git] / dateparse / dateparse_utils.py
index 00e7b9dbb393c4c40be60e0079e0b8377e071ea2..e5e7e76b2a7016cc2142beebbdda3694e879a396 100755 (executable)
@@ -15,11 +15,13 @@ import pytz
 
 import acl
 import bootstrap
-import datetime_utils
-import decorator_utils
+from datetime_utils import (
+    TimeUnit, n_timeunits_from_base, datetime_to_date, date_to_datetime
+)
 from dateparse.dateparse_utilsLexer import dateparse_utilsLexer  # type: ignore
 from dateparse.dateparse_utilsListener import dateparse_utilsListener  # type: ignore
 from dateparse.dateparse_utilsParser import dateparse_utilsParser  # type: ignore
+import decorator_utils
 
 
 logger = logging.getLogger(__name__)
@@ -85,8 +87,11 @@ class RaisingErrorListener(antlr4.DiagnosticErrorListener):
             'enter*',
             'exit*',
         ],
-        denied_patterns=None,
-        order_to_check_allow_deny=acl.ACL_ORDER_DENY_ALLOW,
+        denied_patterns=[
+            'enterEveryRule',
+            'exitEveryRule'
+        ],
+        order_to_check_allow_deny=acl.Order.DENY_ALLOW,
         default_answer=False
     )
 )
@@ -152,16 +157,16 @@ class DateParser(dateparse_utilsListener):
         # These TimeUnits are defined in datetime_utils and are used as params
         # to datetime_utils.n_timeunits_from_base.
         self.time_delta_unit_to_constant = {
-            'hou': datetime_utils.TimeUnit.HOURS,
-            'min': datetime_utils.TimeUnit.MINUTES,
-            'sec': datetime_utils.TimeUnit.SECONDS,
+            'hou': TimeUnit.HOURS,
+            'min': TimeUnit.MINUTES,
+            'sec': TimeUnit.SECONDS,
         }
         self.delta_unit_to_constant = {
-            'day': datetime_utils.TimeUnit.DAYS,
-            'wor': datetime_utils.TimeUnit.WORKDAYS,
-            'wee': datetime_utils.TimeUnit.WEEKS,
-            'mon': datetime_utils.TimeUnit.MONTHS,
-            'yea': datetime_utils.TimeUnit.YEARS,
+            'day': TimeUnit.DAYS,
+            'wor': TimeUnit.WORKDAYS,
+            'wee': TimeUnit.WEEKS,
+            'mon': TimeUnit.MONTHS,
+            'yea': TimeUnit.YEARS,
         }
         self.override_now_for_test_purposes = override_now_for_test_purposes
         self._reset()
@@ -189,6 +194,8 @@ class DateParser(dateparse_utilsListener):
 
         This is the main entrypoint to this class for caller code.
         """
+        date_string = date_string.strip()
+        date_string = re.sub('\s+', ' ', date_string)
         self._reset()
         listener = RaisingErrorListener()
         input_stream = antlr4.InputStream(date_string)
@@ -236,7 +243,7 @@ class DateParser(dateparse_utilsListener):
             self.today = datetime.date.today()
         else:
             self.now_datetime = self.override_now_for_test_purposes
-            self.today = datetime_utils.datetime_to_date(
+            self.today = datetime_to_date(
                 self.override_now_for_test_purposes
             )
         self.date: Optional[datetime.date] = None
@@ -258,10 +265,10 @@ class DateParser(dateparse_utilsListener):
         name = name.replace('washi', 'presi')
         return name
 
-    def _figure_out_date_unit(self, orig: str) -> int:
+    def _figure_out_date_unit(self, orig: str) -> TimeUnit:
         """Figure out what unit a date expression piece is talking about."""
         if 'month' in orig:
-            return datetime_utils.TimeUnit.MONTHS
+            return TimeUnit.MONTHS
         txt = orig.lower()[:3]
         if txt in self.day_name_to_number:
             return(self.day_name_to_number[txt])
@@ -380,7 +387,7 @@ class DateParser(dateparse_utilsListener):
             tz = pytz.timezone(txt)
             if tz is not None:
                 return tz
-        except:
+        except Exception:
             pass
 
         # Try dateutil
@@ -388,7 +395,7 @@ class DateParser(dateparse_utilsListener):
             tz = dateutil.tz.gettz(txt)
             if tz is not None:
                 return tz
-        except:
+        except Exception:
             pass
 
         # Try constructing an offset in seconds
@@ -401,7 +408,7 @@ class DateParser(dateparse_utilsListener):
                 offset = sign * (hour * 60 * 60) + sign * (minute * 60)
                 tzoffset = dateutil.tz.tzoffset(txt, offset)
                 return tzoffset
-        except:
+        except Exception:
             pass
         return None
 
@@ -500,12 +507,12 @@ class DateParser(dateparse_utilsListener):
         if 'delta_unit' not in self.context:
             raise ParseException('Missing delta_unit?!')
         unit = self.context['delta_unit']
-        dt = datetime_utils.n_timeunits_from_base(
+        dt = n_timeunits_from_base(
             count,
             unit,
-            datetime_utils.date_to_datetime(self.date)
+            date_to_datetime(self.date)
         )
-        self.date = datetime_utils.datetime_to_date(dt)
+        self.date = datetime_to_date(dt)
 
     def exitTimeExpr(self, ctx: dateparse_utilsParser.TimeExprContext) -> None:
         # Simple time?
@@ -546,11 +553,11 @@ class DateParser(dateparse_utilsListener):
             self.timedelta += datetime.timedelta(minutes=count)
         else:
             unit = self.context['time_delta_unit']
-            if unit == datetime_utils.TimeUnit.SECONDS:
+            if unit == TimeUnit.SECONDS:
                 self.timedelta += datetime.timedelta(seconds=count)
-            elif unit == datetime_utils.TimeUnit.MINUTES:
+            elif unit == TimeUnit.MINUTES:
                 self.timedelta = datetime.timedelta(minutes=count)
-            elif unit == datetime_utils.TimeUnit.HOURS:
+            elif unit == TimeUnit.HOURS:
                 self.timedelta = datetime.timedelta(hours=count)
             else:
                 raise ParseException()
@@ -569,7 +576,7 @@ class DateParser(dateparse_utilsListener):
             unit = self._figure_out_date_unit(
                 ctx.deltaUnit().getText().lower()
             )
-        except:
+        except Exception:
             raise ParseException(f'Invalid Delta +/-: {ctx.getText()}')
         else:
             self.context['delta_int'] = n
@@ -580,7 +587,7 @@ class DateParser(dateparse_utilsListener):
     ) -> None:
         try:
             unit = self._figure_out_date_unit(ctx.getText().lower())
-        except:
+        except Exception:
             raise ParseException(f'Bad delta unit: {ctx.getText()}')
         else:
             self.context['delta_unit'] = unit
@@ -590,7 +597,7 @@ class DateParser(dateparse_utilsListener):
     ) -> None:
         try:
             txt = ctx.getText().lower()
-        except:
+        except Exception:
             raise ParseException(f'Bad next/last: {ctx.getText()}')
         if (
                 'month' in self.context or
@@ -625,7 +632,7 @@ class DateParser(dateparse_utilsListener):
                 ctx.deltaTimeUnit().getText().lower()
             )
             self.context['time_delta_unit'] = unit
-        except:
+        except Exception:
             raise ParseException(f'Bad delta unit: {ctx.getText()}')
         if 'time_delta_before_after' not in self.context:
             raise ParseException(
@@ -641,15 +648,15 @@ class DateParser(dateparse_utilsListener):
                 self.context['time_delta_int'] = 15
                 self.context[
                     'time_delta_unit'
-                ] = datetime_utils.TimeUnit.MINUTES
+                ] = TimeUnit.MINUTES
             elif txt == 'half':
                 self.context['time_delta_int'] = 30
                 self.context[
                     'time_delta_unit'
-                ] = datetime_utils.TimeUnit.MINUTES
+                ] = TimeUnit.MINUTES
             else:
                 raise ParseException(f'Bad time fraction {ctx.getText()}')
-        except:
+        except Exception:
             raise ParseException(f'Bad time fraction {ctx.getText()}')
 
     def exitDeltaBeforeAfter(
@@ -657,7 +664,7 @@ class DateParser(dateparse_utilsListener):
     ) -> None:
         try:
             txt = ctx.getText().lower()
-        except:
+        except Exception:
             raise ParseException(f'Bad delta before|after: {ctx.getText()}')
         else:
             self.context['delta_before_after'] = txt
@@ -667,7 +674,7 @@ class DateParser(dateparse_utilsListener):
     ) -> None:
         try:
             txt = ctx.getText().lower()
-        except:
+        except Exception:
             raise ParseException(f'Bad delta before|after: {ctx.getText()}')
         else:
             self.context['time_delta_before_after'] = txt
@@ -727,7 +734,7 @@ class DateParser(dateparse_utilsListener):
                 self.context['month'] = month
                 self.context['day'] = 1
             self.main_type = DateParser.PARSE_TYPE_BASE_AND_OFFSET_EXPR
-        except:
+        except Exception:
             raise ParseException(
                 f'Invalid nthWeekday expression: {ctx.getText()}'
             )
@@ -741,7 +748,7 @@ class DateParser(dateparse_utilsListener):
     def exitNth(self, ctx: dateparse_utilsParser.NthContext) -> None:
         try:
             i = self._get_int(ctx.getText())
-        except:
+        except Exception:
             raise ParseException(f'Bad nth expression: {ctx.getText()}')
         else:
             self.context['nth'] = i
@@ -759,7 +766,7 @@ class DateParser(dateparse_utilsListener):
                 raise ParseException(
                     f'Bad first|last expression: {ctx.getText()}'
                 )
-        except:
+        except Exception:
             raise ParseException(f'Bad first|last expression: {ctx.getText()}')
         else:
             self.context['nth'] = txt
@@ -768,7 +775,7 @@ class DateParser(dateparse_utilsListener):
         try:
             dow = ctx.getText().lower()[:3]
             dow = self.day_name_to_number.get(dow, None)
-        except:
+        except Exception:
             raise ParseException('Bad day of week')
         else:
             self.context['dow'] = dow
@@ -792,7 +799,7 @@ class DateParser(dateparse_utilsListener):
                 raise ParseException(
                     f'Bad dayOfMonth expression: {ctx.getText()}'
                 )
-        except:
+        except Exception:
             raise ParseException(f'Bad dayOfMonth expression: {ctx.getText()}')
         self.context['day'] = day
 
@@ -809,7 +816,7 @@ class DateParser(dateparse_utilsListener):
                 raise ParseException(
                     f'Bad monthName expression: {ctx.getText()}'
                 )
-        except:
+        except Exception:
             raise ParseException(f'Bad monthName expression: {ctx.getText()}')
         else:
             self.context['month'] = month
@@ -823,7 +830,7 @@ class DateParser(dateparse_utilsListener):
                 raise ParseException(
                     f'Bad monthNumber expression: {ctx.getText()}'
                 )
-        except:
+        except Exception:
             raise ParseException(
                 f'Bad monthNumber expression: {ctx.getText()}'
             )
@@ -835,7 +842,7 @@ class DateParser(dateparse_utilsListener):
             year = self._get_int(ctx.getText())
             if year < 1:
                 raise ParseException(f'Bad year expression: {ctx.getText()}')
-        except:
+        except Exception:
             raise ParseException(f'Bad year expression: {ctx.getText()}')
         else:
             self.context['year'] = year
@@ -846,7 +853,7 @@ class DateParser(dateparse_utilsListener):
         try:
             special = ctx.specialDate().getText().lower()
             self.context['special'] = special
-        except:
+        except Exception:
             raise ParseException(
                 f'Bad specialDate expression: {ctx.specialDate().getText()}'
             )
@@ -859,7 +866,7 @@ class DateParser(dateparse_utilsListener):
                     self.context['special_next_last'] = 'next'
                 elif mod.LAST() is not None:
                     self.context['special_next_last'] = 'last'
-        except:
+        except Exception:
             raise ParseException(
                 f'Bad specialDateNextLast expression: {ctx.getText()}'
             )
@@ -872,7 +879,7 @@ class DateParser(dateparse_utilsListener):
             count = self._get_int(ctx.unsignedInt().getText())
             unit = ctx.deltaUnit().getText().lower()
             ago_from_now = ctx.AGO_FROM_NOW().getText()
-        except:
+        except Exception:
             raise ParseException(
                 f'Bad NFoosFromTodayAgoExpr: {ctx.getText()}'
             )
@@ -881,7 +888,7 @@ class DateParser(dateparse_utilsListener):
             count = -count
 
         unit = self._figure_out_date_unit(unit)
-        d = datetime_utils.n_timeunits_from_base(
+        d = n_timeunits_from_base(
             count,
             unit,
             d)
@@ -906,12 +913,12 @@ class DateParser(dateparse_utilsListener):
                     f'Bad This/Next/Last modifier: {mod}'
                 )
             unit = ctx.deltaUnit().getText().lower()
-        except:
+        except Exception:
             raise ParseException(
                 f'Bad DeltaRelativeToTodayExpr: {ctx.getText()}'
             )
         unit = self._figure_out_date_unit(unit)
-        d = datetime_utils.n_timeunits_from_base(
+        d = n_timeunits_from_base(
             count,
             unit,
             d)
@@ -924,7 +931,7 @@ class DateParser(dateparse_utilsListener):
     ) -> None:
         try:
             txt = ctx.specialTime().getText().lower()
-        except:
+        except Exception:
             raise ParseException(
                 f'Bad special time expression: {ctx.getText()}'
             )
@@ -945,7 +952,7 @@ class DateParser(dateparse_utilsListener):
         try:
             tz = ctx.tzExpr().getText()
             self.context['tz'] = self._parse_tz(tz)
-        except:
+        except Exception:
             pass
 
     def exitTwelveHourTimeExpr(
@@ -956,14 +963,14 @@ class DateParser(dateparse_utilsListener):
             while not hour[-1].isdigit():
                 hour = hour[:-1]
             hour = self._get_int(hour)
-        except:
+        except Exception:
             raise ParseException(f'Bad hour: {ctx.hour().getText()}')
         if hour <= 0 or hour > 12:
             raise ParseException(f'Bad hour (out of range): {hour}')
 
         try:
             minute = self._get_int(ctx.minute().getText())
-        except:
+        except Exception:
             minute = 0
         if minute < 0 or minute > 59:
             raise ParseException(f'Bad minute (out of range): {minute}')
@@ -971,7 +978,7 @@ class DateParser(dateparse_utilsListener):
 
         try:
             seconds = self._get_int(ctx.second().getText())
-        except:
+        except Exception:
             seconds = 0
         if seconds < 0 or seconds > 59:
             raise ParseException(f'Bad second (out of range): {seconds}')
@@ -979,7 +986,7 @@ class DateParser(dateparse_utilsListener):
 
         try:
             micros = self._get_int(ctx.micros().getText())
-        except:
+        except Exception:
             micros = 0
         if micros < 0 or micros > 1000000:
             raise ParseException(f'Bad micros (out of range): {micros}')
@@ -987,7 +994,7 @@ class DateParser(dateparse_utilsListener):
 
         try:
             ampm = ctx.ampm().getText()
-        except:
+        except Exception:
             raise ParseException(f'Bad ampm: {ctx.ampm().getText()}')
         if hour == 12:
             hour = 0
@@ -998,7 +1005,7 @@ class DateParser(dateparse_utilsListener):
         try:
             tz = ctx.tzExpr().getText()
             self.context['tz'] = self._parse_tz(tz)
-        except:
+        except Exception:
             pass
 
     def exitTwentyFourHourTimeExpr(
@@ -1009,7 +1016,7 @@ class DateParser(dateparse_utilsListener):
             while not hour[-1].isdigit():
                 hour = hour[:-1]
             hour = self._get_int(hour)
-        except:
+        except Exception:
             raise ParseException(f'Bad hour: {ctx.hour().getText()}')
         if hour < 0 or hour > 23:
             raise ParseException(f'Bad hour (out of range): {hour}')
@@ -1017,7 +1024,7 @@ class DateParser(dateparse_utilsListener):
 
         try:
             minute = self._get_int(ctx.minute().getText())
-        except:
+        except Exception:
             minute = 0
         if minute < 0 or minute > 59:
             raise ParseException(f'Bad minute (out of range): {ctx.getText()}')
@@ -1025,7 +1032,7 @@ class DateParser(dateparse_utilsListener):
 
         try:
             seconds = self._get_int(ctx.second().getText())
-        except:
+        except Exception:
             seconds = 0
         if seconds < 0 or seconds > 59:
             raise ParseException(f'Bad second (out of range): {ctx.getText()}')
@@ -1033,7 +1040,7 @@ class DateParser(dateparse_utilsListener):
 
         try:
             micros = self._get_int(ctx.micros().getText())
-        except:
+        except Exception:
             micros = 0
         if micros < 0 or micros >= 1000000:
             raise ParseException(f'Bad micros (out of range): {ctx.getText()}')
@@ -1042,10 +1049,11 @@ class DateParser(dateparse_utilsListener):
         try:
             tz = ctx.tzExpr().getText()
             self.context['tz'] = self._parse_tz(tz)
-        except:
+        except Exception:
             pass
 
 
 def main() -> None:
     parser = DateParser()
     for line in sys.stdin:
@@ -1063,5 +1071,4 @@ def main() -> None:
 
 
 if __name__ == "__main__":
-    main = bootstrap.initialize(main)
     main()