-
Notifications
You must be signed in to change notification settings - Fork 121
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'Precognize-standalone_period_parse_serialize'
- Loading branch information
Showing
6 changed files
with
238 additions
and
133 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import itertools | ||
from datetime import timedelta | ||
|
||
from pyparsing import (Word, ZeroOrMore, alphanums, Or, nums, White, WordEnd) | ||
|
||
period_type_map = { | ||
'nanoseconds': ['ns', 'nano', 'nanos', 'nanosecond', 'nanoseconds'], | ||
|
||
'microseconds': ['us', 'micro', 'micros', 'microsecond', 'microseconds'], | ||
'milliseconds': ['ms', 'milli', 'millis', 'millisecond', 'milliseconds'], | ||
'seconds': ['s', 'second', 'seconds'], | ||
'minutes': ['m', 'minute', 'minutes'], | ||
'hours': ['h', 'hour', 'hours'], | ||
'weeks': ['w', 'week', 'weeks'], | ||
'days': ['d', 'day', 'days'], | ||
|
||
} | ||
|
||
optional_period_type_map = { | ||
'months': ['mo', 'month', 'months'], # 'm' from hocon spec removed. conflicts with minutes syntax. | ||
'years': ['y', 'year', 'years'] | ||
} | ||
|
||
try: | ||
from dateutil.relativedelta import relativedelta as period_impl | ||
|
||
if period_impl is not None: | ||
period_type_map.update(optional_period_type_map) | ||
except ImportError: | ||
period_impl = timedelta | ||
|
||
|
||
def convert_period(tokens): | ||
period_value = int(tokens.value) | ||
period_identifier = tokens.unit | ||
|
||
period_unit = next((single_unit for single_unit, values | ||
in period_type_map.items() | ||
if period_identifier in values)) | ||
|
||
return period(period_value, period_unit) | ||
|
||
|
||
def period(period_value, period_unit): | ||
if period_unit == 'nanoseconds': | ||
period_unit = 'microseconds' | ||
period_value = int(period_value / 1000) | ||
|
||
arguments = dict(zip((period_unit,), (period_value,))) | ||
|
||
if period_unit == 'milliseconds': | ||
return timedelta(**arguments) | ||
|
||
return period_impl(**arguments) | ||
|
||
|
||
def get_period_expr(): | ||
# Flatten the list of lists with unit strings. | ||
period_types = list(itertools.chain(*period_type_map.values())) | ||
# `Or()` tries to match the longest expression if more expressions | ||
# are matching. We employ this to match e.g.: 'weeks' so that we | ||
# don't end up with 'w' and 'eeks'. Note that 'weeks' but also 'w' | ||
# are valid unit identifiers. | ||
# Allow only spaces as a valid separator between value and unit. | ||
# E.g. \t as a separator is invalid: '10<TAB>weeks'. | ||
return ( | ||
Word(nums)('value') + ZeroOrMore(White(ws=' ')).suppress() + Or(period_types)('unit') + WordEnd( | ||
alphanums).suppress() | ||
).setParseAction(convert_period) | ||
|
||
|
||
def parse_period(content): | ||
return get_period_expr().parseString(content, parseAll=True)[0] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
from datetime import timedelta | ||
|
||
try: | ||
from dateutil.relativedelta import relativedelta | ||
except Exception: | ||
relativedelta = None | ||
|
||
|
||
def is_timedelta_like(config): | ||
return isinstance(config, timedelta) or relativedelta is not None and isinstance(config, relativedelta) | ||
|
||
|
||
def timedelta_to_hocon(config): | ||
""":type config: timedelta|relativedelta""" | ||
if relativedelta is not None and isinstance(config, relativedelta): | ||
if config.hours > 0: | ||
return str(config.hours) + ' hours' | ||
elif config.minutes > 0: | ||
return str(config.minutes) + ' minutes' | ||
|
||
if config.days > 0: | ||
return str(config.days) + ' days' | ||
elif config.seconds > 0: | ||
return str(config.seconds) + ' seconds' | ||
elif config.microseconds > 0: | ||
return str(config.microseconds) + ' microseconds' | ||
else: | ||
return '0 seconds' | ||
|
||
|
||
def relative_delta_to_timedelta(relative_delta): | ||
""":type relative_delta: relativedelta""" | ||
return timedelta(days=relative_delta.days, | ||
hours=relative_delta.hours, | ||
minutes=relative_delta.minutes, | ||
seconds=relative_delta.seconds, | ||
microseconds=relative_delta.microseconds) | ||
|
||
|
||
def timedelta_to_str(config): | ||
if isinstance(config, relativedelta): | ||
time_delta = relative_delta_to_timedelta(config) | ||
else: | ||
time_delta = config | ||
return str(int(time_delta.total_seconds() * 1000)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.