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 3 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
2 changes: 1 addition & 1 deletion .github/workflows/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
python-version: "3.8"

runs-on: ${{ matrix.os }}

steps:

#----------------------------------------------
Expand Down
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 @@ def __new__(cls, value: Union[str, datetime.time, datetime.datetime, Literal]) -
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
return str(value)

@classmethod
def is_valid(cls, value: Union[str, datetime.time, datetime.datetime, Literal]) -> bool:
Expand All @@ -260,15 +259,15 @@ def __new__(cls, value: Union[str, datetime.date, Literal]) -> str:
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
return str(value)

@classmethod
def is_valid(cls, value: Union[str, datetime.date, Literal]) -> bool:
Expand All @@ -279,7 +278,10 @@ def is_valid(cls, value: Union[str, datetime.date, Literal]) -> bool:
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 @@ def __new__(cls, value: Union[str, datetime.datetime, Literal]) -> str:
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
return str(value)

@classmethod
def is_valid(cls, value: Union[str, datetime.datetime, Literal]) -> bool:
Expand All @@ -311,8 +316,16 @@ def is_valid(cls, value: Union[str, datetime.datetime, Literal]) -> bool:
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