Commit 26b77fdd authored by Jérome Perrin's avatar Jérome Perrin

utils: parse_tid rework

parent 6ceb2558
......@@ -96,5 +96,4 @@ with open(os.path.join(os.path.dirname(__file__), "testdata", "tidrange-formats.
@pytest.mark.parametrize("reference_time,reference_tid,input_time", test_parameters)
def test_parse_tid(europe_paris_timezone, fake_time, reference_time, reference_tid, input_time):
print ("parsing", input_time, "expecting", reference_time)
assert reference_tid == ashex(parse_tid(input_time))
......@@ -66,40 +66,52 @@ def txnobjv(txn):
class TidRangeInvalid(Exception):
pass
def tid_from_date(date_string):
"""Try to parse `date_string` as a date and returns the
corresponding TID.
If `date_string` cannot be parsed as a date, assume it was
def parse_tid(tid_string, raw_only=False):
"""Try to parse `tid_string` as a time and returns the
corresponding raw TID.
If `tid_string` cannot be parsed as a time, assume it was
already a TID.
This function also raise TidRangeInvalid when `tid_string`
is invalid.
"""
if not date_string:
return date_string
if not tid_string:
return tid_string
# If it "looks like a TID", don't try to parse it as date,
# because parsing as date is slow.
if len(date_string) == 16:
# If it "looks like a TID", don't try to parse it as time,
# because parsing is slow.
if len(tid_string) == 16:
try:
fromhex(date_string)
return date_string
return fromhex(tid_string)
except TypeError:
pass
date = dateparser.parse(
date_string,
settings={
'TO_TIMEZONE': 'UTC'})
date = None
if not raw_only:
# preprocess to support `1.day.ago` style formats like git log does.
if "ago" in tid_string:
tid_string = tid_string.replace(".", " ").replace("_", " ")
date = dateparser.parse(
tid_string,
settings={
'TO_TIMEZONE': 'UTC',
'RETURN_AS_TIMEZONE_AWARE': True
})
if not date:
# parsing failed
return date_string
try:
return fromhex(tid_string)
except TypeError:
raise TidRangeInvalid(tid_string)
# build a ZODB.TimeStamp to convert as a TID
return ashex(
TimeStamp(
return TimeStamp(
date.year,
date.month,
date.day,
date.hour,
date.minute,
date.second + date.microsecond / 1000000.).raw())
date.second + date.microsecond / 1000000.).raw()
# parse_tidrange parses a string into (tidmin, tidmax).
#
......@@ -110,14 +122,8 @@ def parse_tidrange(tidrange):
except ValueError: # not exactly 2 parts in between ".."
raise TidRangeInvalid(tidrange)
tidmin = tid_from_date(tidmin)
tidmax = tid_from_date(tidmax)
try:
tidmin = tidmin.decode("hex")
tidmax = tidmax.decode("hex")
except TypeError: # hex decoding error
raise TidRangeInvalid(tidrange)
tidmin = parse_tid(tidmin)
tidmax = parse_tid(tidmax)
# empty tid means -inf / +inf respectively
# ( which is None in IStorage.iterator() )
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment