--- a/mercurial/utils/dateutil.py Sat Mar 06 15:08:22 2021 -0500
+++ b/mercurial/utils/dateutil.py Sat Mar 06 15:26:46 2021 -0500
@@ -18,6 +18,18 @@
pycompat,
)
+if pycompat.TYPE_CHECKING:
+ from typing import (
+ Callable,
+ Dict,
+ Iterable,
+ Optional,
+ Tuple,
+ Union,
+ )
+
+ hgdate = Tuple[float, int] # (unixtime, offset)
+
# used by parsedate
defaultdateformats = (
b'%Y-%m-%dT%H:%M:%S', # the 'real' ISO8601
@@ -62,6 +74,7 @@
def makedate(timestamp=None):
+ # type: (Optional[float]) -> hgdate
"""Return a unix timestamp (or the current time) as a (unixtime,
offset) tuple based off the local timezone."""
if timestamp is None:
@@ -79,6 +92,7 @@
def datestr(date=None, format=b'%a %b %d %H:%M:%S %Y %1%2'):
+ # type: (Optional[hgdate], bytes) -> bytes
"""represent a (unixtime, offset) tuple as a localized time.
unixtime is seconds since the epoch, and offset is the time zone's
number of seconds away from UTC.
@@ -116,11 +130,13 @@
def shortdate(date=None):
+ # type: (Optional[hgdate]) -> bytes
"""turn (timestamp, tzoff) tuple into iso 8631 date."""
return datestr(date, format=b'%Y-%m-%d')
def parsetimezone(s):
+ # type: (bytes) -> Tuple[Optional[int], bytes]
"""find a trailing timezone, if any, in string, and return a
(offset, remainder) pair"""
s = pycompat.bytestr(s)
@@ -156,6 +172,7 @@
def strdate(string, format, defaults=None):
+ # type: (bytes, bytes, Optional[Dict[bytes, Tuple[bytes, bytes]]]) -> hgdate
"""parse a localized time string and return a (unixtime, offset) tuple.
if the string cannot be parsed, ValueError is raised."""
if defaults is None:
@@ -198,6 +215,7 @@
def parsedate(date, formats=None, bias=None):
+ # type: (Union[bytes, hgdate], Optional[Iterable[bytes]], Optional[Dict[bytes, bytes]]) -> hgdate
"""parse a localized date/time and return a (unixtime, offset) tuple.
The date may be a "unixtime offset" string or in one of the specified
@@ -223,8 +241,11 @@
bias = {}
if not date:
return 0, 0
- if isinstance(date, tuple) and len(date) == 2:
- return date
+ if isinstance(date, tuple):
+ if len(date) == 2:
+ return date
+ else:
+ raise error.ProgrammingError(b"invalid date format")
if not formats:
formats = defaultdateformats
date = date.strip()
@@ -284,6 +305,7 @@
def matchdate(date):
+ # type: (bytes) -> Callable[[float], bool]
"""Return a function that matches a given date match specifier
Formats include:
@@ -313,10 +335,12 @@
"""
def lower(date):
+ # type: (bytes) -> float
d = {b'mb': b"1", b'd': b"1"}
return parsedate(date, extendeddateformats, d)[0]
def upper(date):
+ # type: (bytes) -> float
d = {b'mb': b"12", b'HI': b"23", b'M': b"59", b'S': b"59"}
for days in (b"31", b"30", b"29"):
try: