Skip to content

Commit 8267eb1

Browse files
authored
Refactor annotating literals (#502)
this PR reuses XSD terms from `curies.vocabulary` and adds support for XSD date (as opposed to datetimes)
1 parent 337218c commit 8267eb1

3 files changed

Lines changed: 53 additions & 13 deletions

File tree

src/pyobo/struct/reference.py

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import logging
77
from collections import Counter
88
from collections.abc import Iterable, Sequence
9+
from datetime import date as date_cls
10+
from datetime import datetime as datetime_cls
911
from typing import Any, NamedTuple
1012

1113
import bioregistry
@@ -14,6 +16,7 @@
1416
import pytz
1517
from bioregistry import NormalizedNamableReference as Reference
1618
from curies import ReferenceTuple
19+
from curies import vocabulary as v
1720
from curies.preprocessing import BlocklistError
1821

1922
from ..identifier_utils import (
@@ -304,9 +307,7 @@ def _parse_reference_or_uri_literal(
304307
return None
305308

306309

307-
unspecified_matching = Reference(
308-
prefix="semapv", identifier="UnspecifiedMatching", name="unspecified matching process"
309-
)
310+
unspecified_matching = Reference.from_reference(v.unspecified_matching_process)
310311

311312

312313
class OBOLiteral(NamedTuple):
@@ -319,44 +320,53 @@ class OBOLiteral(NamedTuple):
319320
@classmethod
320321
def string(cls, value: str, *, language: str | None = None) -> OBOLiteral:
321322
"""Get a string literal."""
322-
return cls(value, curies.Reference(prefix="xsd", identifier="string"), language)
323+
return cls(value, v.xsd_string, language)
323324

324325
@classmethod
325326
def boolean(cls, value: bool) -> OBOLiteral:
326327
"""Get a boolean literal."""
327-
return cls(str(value).lower(), curies.Reference(prefix="xsd", identifier="boolean"), None)
328+
return cls(str(value).lower(), v.xsd_boolean, None)
328329

329330
@classmethod
330331
def decimal(cls, value: float) -> OBOLiteral:
331332
"""Get a decimal literal."""
332-
return cls(str(value), curies.Reference(prefix="xsd", identifier="decimal"), None)
333+
return cls(str(value), v.xsd_decimal, None)
333334

334335
@classmethod
335336
def float(cls, value: float) -> OBOLiteral:
336337
"""Get a float literal."""
337-
return cls(str(value), curies.Reference(prefix="xsd", identifier="float"), None)
338+
return cls(str(value), v.xsd_float, None)
338339

339340
@classmethod
340341
def integer(cls, value: int | str) -> OBOLiteral:
341342
"""Get a integer literal."""
342-
return cls(str(int(value)), curies.Reference(prefix="xsd", identifier="integer"), None)
343+
return cls(str(int(value)), v.xsd_integer, None)
343344

344345
@classmethod
345346
def year(cls, value: int | str) -> OBOLiteral:
346347
"""Get a year (gYear) literal."""
347-
return cls(str(int(value)), curies.Reference(prefix="xsd", identifier="gYear"), None)
348+
return cls(str(int(value)), v.xsd_year, None)
348349

349350
@classmethod
350351
def uri(cls, uri: str) -> OBOLiteral:
351352
"""Get a string literal for a URI."""
352-
return cls(uri, curies.Reference(prefix="xsd", identifier="anyURI"), None)
353+
return cls(uri, v.xsd_uri, None)
353354

354355
@classmethod
355-
def datetime(cls, dt: datetime.datetime | str) -> OBOLiteral:
356+
def datetime(cls, dt: datetime_cls | str) -> OBOLiteral:
356357
"""Get a datetime literal."""
357358
if isinstance(dt, str):
358359
dt = _parse_datetime(dt)
359-
return cls(dt.isoformat(), curies.Reference(prefix="xsd", identifier="dateTime"), None)
360+
return cls(dt.isoformat(), v.xsd_datetime, None)
361+
362+
@classmethod
363+
def date(cls, dt: datetime_cls | date_cls | str) -> OBOLiteral:
364+
"""Get a datetime literal."""
365+
if isinstance(dt, str):
366+
dt = datetime.date.fromisoformat(dt)
367+
elif isinstance(dt, datetime.datetime):
368+
dt = dt.date()
369+
return cls(dt.isoformat(), v.xsd_date, None)
360370

361371

362372
def _parse_datetime(dd: str) -> datetime.datetime:

src/pyobo/struct/struct_utils.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,16 @@ def annotate_datetime(
501501
"""Append a datetime annotation."""
502502
return self.annotate_literal(prop, OBOLiteral.datetime(value), annotations=annotations)
503503

504+
def annotate_date(
505+
self,
506+
prop: ReferenceHint,
507+
value: datetime.datetime | datetime.date | str,
508+
*,
509+
annotations: Iterable[Annotation] | None = None,
510+
) -> Self:
511+
"""Append a date annotation."""
512+
return self.annotate_literal(prop, OBOLiteral.date(value), annotations=annotations)
513+
504514
def _iterate_obo_properties(
505515
self,
506516
*,
@@ -976,7 +986,7 @@ def _iterate_obo_relations(
976986
end = reference_escape(value, ontology_prefix=ontology_prefix)
977987
name = value.name
978988
case _:
979-
raise TypeError(f"got unexpected value: {values}")
989+
raise TypeError(f"got unexpected type {type(values)} with value: {values}")
980990
end += _get_obo_trailing_modifiers(
981991
predicate, value, annotations, ontology_prefix=ontology_prefix
982992
)

tests/test_struct/test_obo/test_struct_term.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -771,6 +771,26 @@ def test_12_property_year(self) -> None:
771771
typedefs={RO_DUMMY.pair: RO_DUMMY},
772772
)
773773

774+
def test_12_property_date(self) -> None:
775+
"""Test emitting property literals that were annotated as a date."""
776+
term = Term(reference=LYSINE_DEHYDROGENASE_ACT)
777+
term.annotate_date(RO_DUMMY, "1993-01-01")
778+
self.assert_obo_stanza(
779+
term,
780+
obo="""\
781+
[Term]
782+
id: GO:0050069
783+
name: lysine dehydrogenase activity
784+
property_value: RO:1234567 "1993-01-01" xsd:date
785+
""",
786+
ofn="""\
787+
Declaration(Class(GO:0050069))
788+
AnnotationAssertion(rdfs:label GO:0050069 "lysine dehydrogenase activity")
789+
AnnotationAssertion(RO:1234567 GO:0050069 "1993-01-01"^^xsd:date)
790+
""",
791+
typedefs={RO_DUMMY.pair: RO_DUMMY},
792+
)
793+
774794
def test_12_property_object(self) -> None:
775795
"""Test emitting property literals."""
776796
term = Term(reference=LYSINE_DEHYDROGENASE_ACT)

0 commit comments

Comments
 (0)