Skip to content

Commit

Permalink
Typecheck the temporal module
Browse files Browse the repository at this point in the history
  • Loading branch information
mfisher87 committed Sep 18, 2024
1 parent 3da94ef commit 7b57037
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 33 deletions.
11 changes: 7 additions & 4 deletions icepyx/core/query.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import datetime as dt
import pprint
from typing import Optional, Union, cast

Expand Down Expand Up @@ -126,6 +127,8 @@ class GenQuery:
Quest
"""

_temporal: tp.Temporal

def __init__(
self,
spatial_extent=None,
Expand Down Expand Up @@ -157,7 +160,7 @@ def __str__(self):
# Properties

@property
def temporal(self):
def temporal(self) -> Union[tp.Temporal, list[str]]:
"""
Return the Temporal object containing date/time range information for the query object.
Expand Down Expand Up @@ -254,7 +257,7 @@ def spatial_extent(self):
return (self._spatial._ext_type, self._spatial._spatial_ext)

@property
def dates(self):
def dates(self) -> Union[list[str], list[dt.time]]:
"""
Return an array showing the date range of the query object.
Dates are returned as an array containing the start and end datetime
Expand All @@ -279,7 +282,7 @@ def dates(self):
] # could also use self._start.date()

@property
def start_time(self):
def start_time(self) -> Union[list[str], str]:
"""
Return the start time specified for the start date.
Expand All @@ -303,7 +306,7 @@ def start_time(self):
return self._temporal._start.strftime("%H:%M:%S")

@property
def end_time(self):
def end_time(self) -> Union[list[str], str]:
"""
Return the end time specified for the end date.
Expand Down
78 changes: 49 additions & 29 deletions icepyx/core/temporal.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import datetime as dt
import warnings

"""
Helper functions for validation of dates
"""

import datetime as dt
from typing import Union
import warnings


def convert_string_to_date(date):
def convert_string_to_date(date: str) -> dt.date:
"""
Converts a string to a datetime object.
Throws an error if an invalid format is passed in.
Expand Down Expand Up @@ -49,7 +50,7 @@ def convert_string_to_date(date):
)


def check_valid_date_range(start, end):
def check_valid_date_range(start: dt.date, end: dt.date) -> None:
"""
Helper function for checking if a date range is valid.
Expand Down Expand Up @@ -86,7 +87,10 @@ def check_valid_date_range(start, end):
), "Your date range is invalid; end date MUST be on or after the start date."


def validate_times(start_time, end_time):
def validate_times(
start_time: Union[str, dt.time, None],
end_time: Union[str, dt.time, None],
) -> tuple[dt.time, dt.time]:
"""
Validates the start and end times passed into __init__ and returns them as datetime.time objects.
Expand Down Expand Up @@ -141,7 +145,11 @@ def validate_times(start_time, end_time):
return start_time, end_time


def validate_date_range_datestr(date_range, start_time=None, end_time=None):
def validate_date_range_datestr(
date_range: list[str],
start_time: Union[str, dt.time, None] = None,
end_time: Union[str, dt.time, None] = None,
) -> tuple[dt.datetime, dt.datetime]:
"""
Validates a date range provided in the form of a list of strings.
Expand All @@ -150,12 +158,10 @@ def validate_date_range_datestr(date_range, start_time=None, end_time=None):
Parameters
----------
date_range: list(str)
date_range:
A date range provided in the form of a list of strings
Strings must be of formats accepted by validate_inputs_temporal.convert_string_to_date().
List must be of length 2.
start_time: string, datetime.time, None
end_time: string, datetime.time, None
Returns
-------
Expand Down Expand Up @@ -185,17 +191,19 @@ def validate_date_range_datestr(date_range, start_time=None, end_time=None):
return _start, _end


def validate_date_range_datetime(date_range, start_time=None, end_time=None):
def validate_date_range_datetime(
date_range: list[dt.datetime],
start_time: Union[str, dt.time, None] = None,
end_time: Union[str, dt.time, None] = None,
) -> tuple[dt.datetime, dt.datetime]:
"""
Validates a date range provided in the form of a list of datetimes.
Parameters
----------
date_range: list(datetime.datetime)
date_range:
A date range provided in the form of a list of datetimes.
List must be of length 2.
start_time: None, string, datetime.time
end_time: None, string, datetime.time
NOTE: If start and/or end times are given,
they will be **ignored** in favor of the time from the start/end datetime.datetime objects.
Expand Down Expand Up @@ -224,7 +232,11 @@ def validate_date_range_datetime(date_range, start_time=None, end_time=None):
return date_range[0], date_range[1]


def validate_date_range_date(date_range, start_time=None, end_time=None):
def validate_date_range_date(
date_range: list[dt.date],
start_time: Union[str, dt.time, None] = None,
end_time: Union[str, dt.time, None] = None,
):
"""
Validates a date range provided in the form of a list of datetime.date objects.
Expand All @@ -233,11 +245,9 @@ def validate_date_range_date(date_range, start_time=None, end_time=None):
Parameters
----------
date_range: list(str)
date_range:
A date range provided in the form of a list of datetime.dates.
List must be of length 2.
start_time: string or datetime.time
end_time: string or datetime.time
Returns
-------
Expand All @@ -261,14 +271,18 @@ def validate_date_range_date(date_range, start_time=None, end_time=None):
return _start, _end


def validate_date_range_dict(date_range, start_time=None, end_time=None):
def validate_date_range_dict(
date_range: dict[str, dt.datetime],
start_time: Union[str, dt.time, None] = None,
end_time: Union[str, dt.time, None] = None,
) -> tuple[dt.datetime, dt.datetime]:
"""
Validates a date range provided in the form of a dict with the following keys:
Parameters
----------
date_range: dict(str, datetime.datetime, datetime.date)
date_range:
A date range provided in the form of a dict.
date_range must contain only the following keys:
* `start_date`: start date, type can be of dt.datetime, dt.date, or string
Expand All @@ -278,8 +292,6 @@ def validate_date_range_dict(date_range, start_time=None, end_time=None):
If the values are of type dt.datetime and were created without times,
the datetime package defaults of all 0s are used and
the start_time/end_time parameters will be ignored!
start_time: string or datetime.time
end_time: string or datetime.time
Returns
Expand Down Expand Up @@ -366,7 +378,15 @@ def validate_date_range_dict(date_range, start_time=None, end_time=None):


class Temporal:
def __init__(self, date_range, start_time=None, end_time=None):
_start: dt.datetime
_end: dt.datetime

def __init__(
self,
date_range: Union[list, dict],
start_time: Union[str, dt.time, None] = None,
end_time: Union[str, dt.time, None] = None,
):
"""
Validates input from "date_range" argument (and start/end time arguments, if provided),
then creates a Temporal object with validated inputs as properties of the object.
Expand All @@ -376,7 +396,7 @@ def __init__(self, date_range, start_time=None, end_time=None):
Parameters
----------
date_range : list or dict, as follows
date_range :
Date range of interest, provided as start and end dates, inclusive.
Accepted input date formats are:
* YYYY-MM-DD string
Expand All @@ -387,13 +407,13 @@ def __init__(self, date_range, start_time=None, end_time=None):
Date inputs are accepted as a list or dictionary with `start_date` and `end_date` keys.
Currently, a list of specific dates (rather than a range) is not accepted.
TODO: allow searches with a list of dates, rather than a range.
start_time : str, datetime.time, default None
start_time :
Start time in UTC/Zulu (24 hour clock).
Input types are an HH:mm:ss string or datetime.time object
where HH = hours, mm = minutes, ss = seconds.
If None is given (and a datetime.datetime object is not supplied for `date_range`),
a default of 00:00:00 is applied.
end_time : str, datetime.time, default None
end_time :
End time in UTC/Zulu (24 hour clock).
Input types are an HH:mm:ss string or datetime.time object
where HH = hours, mm = minutes, ss = seconds.
Expand Down Expand Up @@ -444,14 +464,14 @@ def __init__(self, date_range, start_time=None, end_time=None):
"Your date range list is the wrong length. It should be of length 2, with start and end dates only."
)

def __str__(self):
def __str__(self) -> str:
return "Start date and time: {0}\nEnd date and time: {1}".format(
self._start.strftime("%Y-%m-%d %H:%M:%S"),
self._end.strftime("%Y-%m-%d %H:%M:%S"),
)

@property
def start(self):
def start(self) -> dt.datetime:
"""
Return the start date and time of the Temporal object as a datetime.datetime object.
Expand All @@ -465,7 +485,7 @@ def start(self):
return self._start

@property
def end(self):
def end(self) -> dt.datetime:
"""
Return the end date and time of the Temporal object as a datetime.datetime object.
Expand Down

0 comments on commit 7b57037

Please sign in to comment.