Skip to content

Commit

Permalink
Fix default reference output in OBO flat file format (#261)
Browse files Browse the repository at this point in the history
This fixes an issue where default terms of the form of
`obo:<prefix>#<identifier>` weren't properly serialized to OBO flat file
  • Loading branch information
cthoyt authored Dec 3, 2024
1 parent 15ff667 commit 37bb8d4
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 11 deletions.
14 changes: 9 additions & 5 deletions src/pyobo/struct/reference.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,12 +185,16 @@ def default_reference(prefix: str, identifier: str, name: str | None = None) ->
return Reference(prefix="obo", identifier=f"{prefix}#{identifier}", name=name)


def reference_escape(predicate: Reference | Referenced, *, ontology_prefix: str) -> str:
def reference_escape(
reference: Reference | Referenced, *, ontology_prefix: str, add_name_comment: bool = False
) -> str:
"""Write a reference with default namespace removed."""
if predicate.prefix == "obo" and predicate.identifier.startswith(f"{ontology_prefix}#"):
return predicate.identifier.removeprefix(f"{ontology_prefix}#")
else:
return predicate.preferred_curie
if reference.prefix == "obo" and reference.identifier.startswith(f"{ontology_prefix}#"):
return reference.identifier.removeprefix(f"{ontology_prefix}#")
rv = reference.preferred_curie
if add_name_comment and reference.name:
rv += f" ! {reference.name}"
return rv


def comma_separate_references(references: list[Reference]) -> str:
Expand Down
16 changes: 10 additions & 6 deletions src/pyobo/struct/struct.py
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ def iterate_obo_lines(
) -> Iterable[str]:
"""Iterate over the lines to write in an OBO file."""
yield f"\n[{self.type}]"
yield f"id: {self.preferred_curie}"
yield f"id: {self._reference(self.reference, ontology_prefix)}"
if self.is_obsolete:
yield "is_obsolete: true"
if self.name:
Expand All @@ -543,14 +543,14 @@ def iterate_obo_lines(
yield f"def: {self._definition_fp()}"

for alt in sorted(self.alt_ids):
yield f"alt_id: {alt}" # __str__ bakes in the ! name
yield f"alt_id: {self._reference(alt, ontology_prefix, add_name_comment=True)}"

for xref in sorted(xrefs):
yield f"xref: {xref}" # __str__ bakes in the ! name
yield f"xref: {self._reference(xref, ontology_prefix, add_name_comment=True)}"

parent_tag = "is_a" if self.type == "Term" else "instance_of"
for parent in sorted(self.parents):
yield f"{parent_tag}: {parent}" # __str__ bakes in the ! name
yield f"{parent_tag}: {self._reference(parent, ontology_prefix, add_name_comment=True)}"

if emit_object_properties:
yield from self._emit_relations(ontology_prefix, typedefs)
Expand Down Expand Up @@ -608,8 +608,12 @@ def _emit_literal_properties(
yield f'{predicate_curie} "{value}" {datatype.preferred_curie}'

@staticmethod
def _reference(predicate: Reference, ontology_prefix: str) -> str:
return reference_escape(predicate, ontology_prefix=ontology_prefix)
def _reference(
predicate: Reference, ontology_prefix: str, add_name_comment: bool = False
) -> str:
return reference_escape(
predicate, ontology_prefix=ontology_prefix, add_name_comment=add_name_comment
)

@staticmethod
def _escape(s) -> str:
Expand Down
12 changes: 12 additions & 0 deletions tests/test_struct.py
Original file line number Diff line number Diff line change
Expand Up @@ -520,3 +520,15 @@ def test_see_also_double(self) -> None:

self.assertIsNone(term.get_relationship(exact_match))
self.assertIsNone(term.get_species())

def test_default_term(self) -> None:
"""Test when a term uses a default reference."""
term = Term(reference=default_reference("gard", identifier="genetics", name="Genetics"))
self.assert_lines(
"""\
[Term]
id: genetics
name: Genetics
""",
term.iterate_obo_lines(ontology_prefix="gard", typedefs={}),
)

0 comments on commit 37bb8d4

Please sign in to comment.