"""
Imports and classes required to ensure compatibility with Pyam is intelligently handled.
"""
import datetime
from dateutil import parser
try:
from pyam import IamDataFrame # type: ignore
# mypy can't work out try-except block forces IamDataFrame to be here
[docs] class LongDatetimeIamDataFrame(IamDataFrame): # type: ignore
"""
Custom implementation of :class:`pyam.IamDataFrame` which handles long datetime data.
This custom implementation allows the data frame to handle times outside panda's
limited time range of 1677-09-22 00:12:43.145225 to 2262-04-11
23:47:16.854775807, see `this discussion
<https://stackoverflow.com/a/37226672>`_.
TODO: use np.datetime64 instead
"""
def _format_datetime_col(self):
if self.data["time"].apply(lambda x: isinstance(x, str)).any():
def convert_str_to_datetime(inp):
try:
return parser.parse(inp)
except ValueError:
return inp
self.data["time"] = self.data["time"].apply(convert_str_to_datetime)
not_datetime = [
not isinstance(x, (datetime.datetime, datetime.date))
for x in self.data["time"]
]
if any(not_datetime):
bad_values = self.data[not_datetime]["time"]
error_msg = (
"All time values must be convertible to datetime. The following "
f"values are not:\n{bad_values}"
)
raise ValueError(error_msg)
except ImportError: # pragma: no cover
# mypy can't work out try-except block sets typing
IamDataFrame = None
LongDatetimeIamDataFrame = None # type: ignore
__all__ = ["IamDataFrame", "LongDatetimeIamDataFrame"]