-
Notifications
You must be signed in to change notification settings - Fork 130
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move date logic from filter to utils
With #740, filter's numeric_date() provides support for 3 date formats. However, supporting various date formats is not specific to filter (e.g. frequencies has a separate numeric_date() which is now out-of-sync with this filter's numeric_date()). This commit: 1. Moves numeric_date() to a new submodule augur.utils.date_parsing 2. Moves the related SUPPORTED_DATE_HELP_TEXT to augur.utils.date_parsing 3. Updates numeric_date() to raise a TypeError rather than argparse.ArgumentTypeError so it can be generalized to non-argparse usage 4. Adds a new function numeric_date_type() which wraps numeric_date() and raises an argparse.ArgumentTypeError per #740 (comment)
- Loading branch information
Showing
3 changed files
with
77 additions
and
64 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import argparse | ||
import datetime | ||
from textwrap import dedent | ||
import isodate | ||
import treetime.utils | ||
|
||
SUPPORTED_DATE_HELP_TEXT = dedent("""\ | ||
1. an Augur-style numeric date with the year as the integer part (e.g. 2020.42) or | ||
2. a date in ISO 8601 date format (i.e. YYYY-MM-DD) (e.g. '2020-06-04') or | ||
3. a backwards-looking relative date in ISO 8601 duration format with optional P prefix (e.g. '1W', 'P1W') | ||
""") | ||
|
||
def numeric_date(date): | ||
""" | ||
Converts the given *date* string to a :py:class:`float`. | ||
*date* may be given as: | ||
1. A string or float (number) with year as the integer part | ||
2. A string in the YYYY-MM-DD (ISO 8601) syntax | ||
3. A string representing a relative date (duration before datetime.date.today()) | ||
>>> numeric_date("2020.42") | ||
2020.42 | ||
>>> numeric_date("2020-06-04") | ||
2020.42486... | ||
>>> import datetime, isodate, treetime | ||
>>> numeric_date("1W") == treetime.utils.numeric_date(datetime.date.today() - isodate.parse_duration("P1W")) | ||
True | ||
""" | ||
# date is numeric | ||
try: | ||
return float(date) | ||
except ValueError: | ||
pass | ||
|
||
# date is in YYYY-MM-DD form | ||
try: | ||
return treetime.utils.numeric_date(datetime.date(*map(int, date.split("-", 2)))) | ||
except ValueError: | ||
pass | ||
|
||
# date is a duration treated as a backwards-looking relative date | ||
try: | ||
# make a copy of date for this block | ||
duration_str = str(date) | ||
if duration_str.startswith('P'): | ||
duration_str = duration_str | ||
else: | ||
duration_str = 'P'+duration_str | ||
return treetime.utils.numeric_date(datetime.date.today() - isodate.parse_duration(duration_str)) | ||
except (ValueError, isodate.ISO8601Error): | ||
pass | ||
|
||
raise ValueError(f"""Unable to determine date from '{date}'. Ensure it is in one of the supported formats:\n{SUPPORTED_DATE_HELP_TEXT}""") | ||
|
||
def numeric_date_type(date): | ||
"""Wraps numeric_date() for argparse usage. | ||
This raises an ArgumentTypeError, otherwise the custom exception message won't be shown console output due to: | ||
https://github.com/python/cpython/blob/5c4d1f6e0e192653560ae2941a6677fbf4fbd1f2/Lib/argparse.py#L2503-L2513 | ||
""" | ||
try: | ||
return numeric_date(date) | ||
except ValueError as e: | ||
raise argparse.ArgumentTypeError(str(e)) from e |
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