csvw
csvw copied to clipboard
Check alternatives for dependency on python-dateutil
See https://github.com/dateutil/dateutil/issues/1404
For python >= 3.11 the following changes remove the dependency on python-dateutil:
diff --git a/src/csvw/datatypes.py b/src/csvw/datatypes.py
index ad17973..e7c155b 100644
--- a/src/csvw/datatypes.py
+++ b/src/csvw/datatypes.py
@@ -22,7 +22,6 @@ import collections
import isodate
import rfc3986
-import dateutil.parser
import babel.numbers
import babel.dates
import jsonschema
@@ -288,13 +287,26 @@ def with_tz(v, func, args, kw):
tz = tz.groups()[0]
res = func(v, *args, **kw)
if tz:
- dt = dateutil.parser.parse('{}{}'.format(datetime.datetime.now(), tz))
+ dt = datetime.datetime.strptime(tz, '%z')
res = datetime.datetime(
res.year, res.month, res.day, res.hour, res.minute, res.second, res.microsecond,
dt.tzinfo)
return res
+def _tzinfo(v):
+ res = v.split()[-1]
+ try:
+ return datetime.datetime.strptime(res, '%Z').tzinfo
+ except ValueError:
+ pass
+ if re.fullmatch(r'[+-][0-9]{2}', res):
+ res += '00'
+ if ':' in res:
+ res = res.replace(':', '')
+ return datetime.datetime.strptime(res, '%z').tzinfo
+
+
@register
class dateTime(anyAtomicType):
"""
@@ -329,8 +341,7 @@ class dateTime(anyAtomicType):
comps[a] = getattr(d, a)
res = cls(**{k: int(v) for k, v in comps.items() if v is not None})
if tz_marker:
- # Let dateutils take care of parsing the timezone info:
- res = res.replace(tzinfo=dateutil.parser.parse(v).tzinfo)
+ res = res.replace(tzinfo=_tzinfo(v))
return res
@staticmethod
@@ -340,7 +351,7 @@ class dateTime(anyAtomicType):
if not match:
raise ValueError('{} -- {} -- {}'.format(pattern, v, regex)) # pragma:
try:
- return dateutil.parser.isoparse(v)
+ return datetime.datetime.fromisoformat(v)
except ValueError:
return dateTime._parse(v, datetime.datetime, regex, tz_marker=tz_marker)
@@ -419,7 +430,8 @@ class _time(dateTime):
@staticmethod
def to_python(v, regex=None, fmt=None, tz_marker=None, pattern=None):
if pattern and 'x' in pattern.lower():
- return dateutil.parser.parse('{}T{}'.format(datetime.date.today().isoformat(), v))
+ return datetime.datetime.fromisoformat(
+ '{}T{}'.format(datetime.date.today().isoformat(), v))
assert regex is not None
return with_tz(v, dateTime._parse, [datetime.datetime, regex], dict(tz_marker=tz_marker))