Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support isodate ending with Z #357

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 39 additions & 26 deletions linkml_runtime/utils/metamodelcore.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
import re
from dataclasses import field
from decimal import Decimal
import sys
from typing import Union, Optional, Tuple
from urllib.parse import urlparse

import isodate
from rdflib import Literal, BNode, URIRef
from rdflib.namespace import is_ncname
from rdflib.term import Identifier as rdflib_Identifier
Expand Down Expand Up @@ -230,13 +232,10 @@
if not isinstance(value, datetime.time):
value = datetime.time.fromisoformat(value)
return datetime.time.fromisoformat(str(value)).isoformat()
except TypeError as e:
pass
except ValueError as e:
pass
if not is_strict():
return str(value)
raise e
except (TypeError, ValueError) as e:
if is_strict():
raise e

Check warning on line 237 in linkml_runtime/utils/metamodelcore.py

View check run for this annotation

Codecov / codecov/patch

linkml_runtime/utils/metamodelcore.py#L237

Added line #L237 was not covered by tests
return str(value)

@classmethod
def is_valid(cls, value: Union[str, datetime.time, datetime.datetime, Literal]) -> bool:
Expand All @@ -260,15 +259,15 @@
value = value.value
try:
if not isinstance(value, datetime.date):
value = datetime.date.fromisoformat(str(value))
if sys.version_info >= (3, 11):
value = datetime.date.fromisoformat(str(value))
else:
value = isodate.parse_date(value)
return value.isoformat()
except TypeError as e:
pass
except ValueError as e:
pass
if not is_strict():
return str(value)
raise e
except (TypeError, ValueError) as e:
if is_strict():
raise e

Check warning on line 269 in linkml_runtime/utils/metamodelcore.py

View check run for this annotation

Codecov / codecov/patch

linkml_runtime/utils/metamodelcore.py#L269

Added line #L269 was not covered by tests
return str(value)

@classmethod
def is_valid(cls, value: Union[str, datetime.date, Literal]) -> bool:
Expand All @@ -279,7 +278,10 @@
if not re.match(r'^\d{4}-\d{2}-\d{2}$', value):
return False
try:
datetime.date.fromisoformat(str(value))
if sys.version_info >= (3, 11):
datetime.date.fromisoformat(str(value))
else:
value = isodate.parse_date(value)
except ValueError:
return False
return True
Expand All @@ -294,15 +296,18 @@
value = value.value
try:
if not isinstance(value, datetime.datetime):
value = datetime.datetime.fromisoformat(value) # Note that this handles non 'T' format as well
if sys.version_info >= (3, 11):
value = datetime.datetime.fromisoformat(value) # Note that this handles non 'T' format as well
else:
if "T" in str(value):
value = isodate.parse_datetime(value)
else:
value = isodate.parse_datetime("T".join(value.strip().split(' ', 1)))
return value.isoformat()
except TypeError as e:
pass
except ValueError as e:
pass
if not is_strict():
return str(value)
raise e
except (TypeError, ValueError) as e:
if is_strict():
raise e

Check warning on line 309 in linkml_runtime/utils/metamodelcore.py

View check run for this annotation

Codecov / codecov/patch

linkml_runtime/utils/metamodelcore.py#L309

Added line #L309 was not covered by tests
return str(value)

@classmethod
def is_valid(cls, value: Union[str, datetime.datetime, Literal]) -> bool:
Expand All @@ -311,8 +316,16 @@
if isinstance(value, datetime.datetime):
value = value.isoformat()
try:
datetime.datetime.fromisoformat(value)
except ValueError:
if sys.version_info >= (3, 11):
datetime.datetime.fromisoformat(value)
else:
if "T" in str(value):
isodate.parse_datetime(value)
elif " " in value.strip():
isodate.parse_datetime("T".join(value.strip().split(' ', 1)))
else:
datetime.datetime.fromisoformat(value)
except (ValueError, TypeError):
return False
return True

Expand Down
5 changes: 5 additions & 0 deletions tests/test_utils/test_metamodelcore.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ def test_time(self):
XSDDate(datetime.datetime.now())
self.assertFalse(XSDTime.is_valid('Jan 12, 2019'))
self.assertFalse(XSDTime.is_valid(datetime.datetime.now()))
self.assertFalse(XSDTime.is_valid("2019-07-06T17:22:39Z"))
self.assertTrue(XSDTime.is_valid(v))

def test_date(self):
Expand All @@ -168,6 +169,9 @@ def test_date(self):
XSDDate('Jan 12, 2019')
with self.assertRaises(ValueError):
XSDDate(datetime.datetime.now())
with self.assertRaises(ValueError):
XSDDate("2019-07-06T17:22:39Z")

lax()
bv = XSDDate('Jan 12, 2019')
self.assertEqual('Jan 12, 2019', bv)
Expand All @@ -188,6 +192,7 @@ def test_datetime(self):
vstr = str(Literal(v).value)
self.assertEqual('2019-07-06 17:22:39.007300', vstr) # Note that this has no 'T'
self.assertEqual('2019-07-06T17:22:39.007300', XSDDateTime(vstr))
self.assertEqual('2019-07-06T17:22:39+00:00', XSDDateTime("2019-07-06T17:22:39Z"))
with self.assertRaises(ValueError):
XSDDateTime('Jan 12, 2019')
lax()
Expand Down
16 changes: 7 additions & 9 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
[tox]
envlist = py37, py38, py39, py310
isolated_build = true
skipsdist = true

envlist = py39, py310, py311, py312

[testenv]
whitelist_externals = poetry
commands=
poetry install -v
poetry run python -m unittest
poetry run comparefiles --help
skip_install = true
allowlist_externals = poetry
commands_pre =
poetry install
commands =
poetry run pytest
Loading