pyobo 0.10.12__py3-none-any.whl → 0.11.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. pyobo/__init__.py +0 -2
  2. pyobo/__main__.py +0 -2
  3. pyobo/api/__init__.py +0 -2
  4. pyobo/api/alts.py +6 -7
  5. pyobo/api/hierarchy.py +14 -15
  6. pyobo/api/metadata.py +3 -4
  7. pyobo/api/names.py +31 -32
  8. pyobo/api/properties.py +6 -7
  9. pyobo/api/relations.py +12 -11
  10. pyobo/api/species.py +5 -6
  11. pyobo/api/typedefs.py +1 -3
  12. pyobo/api/utils.py +61 -5
  13. pyobo/api/xrefs.py +4 -5
  14. pyobo/aws.py +3 -5
  15. pyobo/cli/__init__.py +0 -2
  16. pyobo/cli/aws.py +0 -2
  17. pyobo/cli/cli.py +0 -4
  18. pyobo/cli/database.py +1 -3
  19. pyobo/cli/lookup.py +0 -2
  20. pyobo/cli/utils.py +0 -2
  21. pyobo/constants.py +0 -33
  22. pyobo/getters.py +19 -26
  23. pyobo/gilda_utils.py +9 -10
  24. pyobo/identifier_utils.py +10 -10
  25. pyobo/mocks.py +5 -6
  26. pyobo/normalizer.py +24 -24
  27. pyobo/obographs.py +3 -3
  28. pyobo/plugins.py +3 -4
  29. pyobo/py.typed +0 -0
  30. pyobo/reader.py +19 -21
  31. pyobo/registries/__init__.py +0 -2
  32. pyobo/registries/metaregistry.py +6 -8
  33. pyobo/resource_utils.py +1 -3
  34. pyobo/resources/__init__.py +0 -2
  35. pyobo/resources/ncbitaxon.py +2 -3
  36. pyobo/resources/ro.py +2 -4
  37. pyobo/sources/README.md +15 -0
  38. pyobo/sources/__init__.py +0 -2
  39. pyobo/sources/agrovoc.py +3 -3
  40. pyobo/sources/antibodyregistry.py +2 -3
  41. pyobo/sources/biogrid.py +4 -4
  42. pyobo/sources/ccle.py +3 -4
  43. pyobo/sources/cgnc.py +1 -3
  44. pyobo/sources/chebi.py +2 -4
  45. pyobo/sources/chembl.py +1 -3
  46. pyobo/sources/civic_gene.py +2 -3
  47. pyobo/sources/complexportal.py +3 -5
  48. pyobo/sources/conso.py +2 -4
  49. pyobo/sources/cpt.py +1 -3
  50. pyobo/sources/credit.py +1 -1
  51. pyobo/sources/cvx.py +1 -3
  52. pyobo/sources/depmap.py +3 -4
  53. pyobo/sources/dictybase_gene.py +1 -3
  54. pyobo/sources/drugbank.py +6 -7
  55. pyobo/sources/drugbank_salt.py +3 -4
  56. pyobo/sources/drugcentral.py +5 -7
  57. pyobo/sources/expasy.py +11 -12
  58. pyobo/sources/famplex.py +3 -5
  59. pyobo/sources/flybase.py +2 -4
  60. pyobo/sources/geonames.py +1 -1
  61. pyobo/sources/gmt_utils.py +5 -6
  62. pyobo/sources/go.py +4 -6
  63. pyobo/sources/gwascentral_phenotype.py +1 -3
  64. pyobo/sources/gwascentral_study.py +2 -3
  65. pyobo/sources/hgnc.py +6 -7
  66. pyobo/sources/hgncgenefamily.py +2 -4
  67. pyobo/sources/icd10.py +3 -4
  68. pyobo/sources/icd11.py +3 -4
  69. pyobo/sources/icd_utils.py +6 -7
  70. pyobo/sources/interpro.py +3 -5
  71. pyobo/sources/itis.py +1 -3
  72. pyobo/sources/kegg/__init__.py +0 -2
  73. pyobo/sources/kegg/api.py +3 -4
  74. pyobo/sources/kegg/genes.py +3 -4
  75. pyobo/sources/kegg/genome.py +1 -3
  76. pyobo/sources/kegg/pathway.py +5 -6
  77. pyobo/sources/mesh.py +19 -21
  78. pyobo/sources/mgi.py +1 -3
  79. pyobo/sources/mirbase.py +4 -6
  80. pyobo/sources/mirbase_constants.py +0 -2
  81. pyobo/sources/mirbase_family.py +1 -3
  82. pyobo/sources/mirbase_mature.py +1 -3
  83. pyobo/sources/msigdb.py +4 -5
  84. pyobo/sources/ncbigene.py +3 -5
  85. pyobo/sources/npass.py +1 -3
  86. pyobo/sources/omim_ps.py +1 -3
  87. pyobo/sources/pathbank.py +3 -5
  88. pyobo/sources/pfam.py +1 -3
  89. pyobo/sources/pfam_clan.py +1 -3
  90. pyobo/sources/pid.py +3 -5
  91. pyobo/sources/pombase.py +1 -3
  92. pyobo/sources/pubchem.py +2 -3
  93. pyobo/sources/reactome.py +2 -4
  94. pyobo/sources/rgd.py +2 -3
  95. pyobo/sources/rhea.py +7 -8
  96. pyobo/sources/ror.py +3 -2
  97. pyobo/sources/selventa/__init__.py +0 -2
  98. pyobo/sources/selventa/schem.py +1 -3
  99. pyobo/sources/selventa/scomp.py +1 -3
  100. pyobo/sources/selventa/sdis.py +1 -3
  101. pyobo/sources/selventa/sfam.py +1 -3
  102. pyobo/sources/sgd.py +1 -3
  103. pyobo/sources/slm.py +1 -3
  104. pyobo/sources/umls/__init__.py +0 -2
  105. pyobo/sources/umls/__main__.py +0 -2
  106. pyobo/sources/umls/get_synonym_types.py +1 -1
  107. pyobo/sources/umls/umls.py +2 -4
  108. pyobo/sources/uniprot/__init__.py +0 -2
  109. pyobo/sources/uniprot/uniprot.py +4 -4
  110. pyobo/sources/uniprot/uniprot_ptm.py +6 -5
  111. pyobo/sources/utils.py +3 -5
  112. pyobo/sources/wikipathways.py +1 -3
  113. pyobo/sources/zfin.py +2 -3
  114. pyobo/ssg/__init__.py +3 -2
  115. pyobo/struct/__init__.py +0 -2
  116. pyobo/struct/reference.py +13 -15
  117. pyobo/struct/struct.py +102 -96
  118. pyobo/struct/typedef.py +9 -10
  119. pyobo/struct/utils.py +0 -2
  120. pyobo/utils/__init__.py +0 -2
  121. pyobo/utils/cache.py +14 -6
  122. pyobo/utils/io.py +9 -10
  123. pyobo/utils/iter.py +5 -6
  124. pyobo/utils/misc.py +1 -3
  125. pyobo/utils/ndex_utils.py +6 -7
  126. pyobo/utils/path.py +4 -5
  127. pyobo/version.py +3 -5
  128. pyobo/xrefdb/__init__.py +0 -2
  129. pyobo/xrefdb/canonicalizer.py +27 -18
  130. pyobo/xrefdb/priority.py +0 -2
  131. pyobo/xrefdb/sources/__init__.py +3 -4
  132. pyobo/xrefdb/sources/biomappings.py +0 -2
  133. pyobo/xrefdb/sources/cbms2019.py +0 -2
  134. pyobo/xrefdb/sources/chembl.py +0 -2
  135. pyobo/xrefdb/sources/compath.py +1 -3
  136. pyobo/xrefdb/sources/famplex.py +3 -5
  137. pyobo/xrefdb/sources/gilda.py +0 -2
  138. pyobo/xrefdb/sources/intact.py +5 -5
  139. pyobo/xrefdb/sources/ncit.py +1 -3
  140. pyobo/xrefdb/sources/pubchem.py +2 -5
  141. pyobo/xrefdb/sources/wikidata.py +2 -4
  142. pyobo/xrefdb/xrefs_pipeline.py +15 -16
  143. {pyobo-0.10.12.dist-info → pyobo-0.11.0.dist-info}/LICENSE +1 -1
  144. pyobo-0.11.0.dist-info/METADATA +723 -0
  145. pyobo-0.11.0.dist-info/RECORD +171 -0
  146. {pyobo-0.10.12.dist-info → pyobo-0.11.0.dist-info}/WHEEL +1 -1
  147. pyobo-0.11.0.dist-info/entry_points.txt +2 -0
  148. pyobo-0.10.12.dist-info/METADATA +0 -499
  149. pyobo-0.10.12.dist-info/RECORD +0 -169
  150. pyobo-0.10.12.dist-info/entry_points.txt +0 -15
  151. {pyobo-0.10.12.dist-info → pyobo-0.11.0.dist-info}/top_level.txt +0 -0
pyobo/struct/struct.py CHANGED
@@ -1,5 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
-
3
1
  """Data structures for OBO."""
4
2
 
5
3
  import gzip
@@ -7,6 +5,7 @@ import json
7
5
  import logging
8
6
  import os
9
7
  from collections import defaultdict
8
+ from collections.abc import Collection, Iterable, Iterator, Mapping, Sequence
10
9
  from dataclasses import dataclass, field
11
10
  from datetime import datetime
12
11
  from operator import attrgetter
@@ -16,17 +15,8 @@ from typing import (
16
15
  Any,
17
16
  Callable,
18
17
  ClassVar,
19
- Collection,
20
- Dict,
21
- Iterable,
22
- Iterator,
23
- List,
24
- Mapping,
25
18
  Optional,
26
- Sequence,
27
- Set,
28
19
  TextIO,
29
- Tuple,
30
20
  Union,
31
21
  )
32
22
 
@@ -104,7 +94,7 @@ class Synonym:
104
94
  )
105
95
 
106
96
  #: References to articles where the synonym appears
107
- provenance: List[Reference] = field(default_factory=list)
97
+ provenance: list[Reference] = field(default_factory=list)
108
98
 
109
99
  def to_obo(self) -> str:
110
100
  """Write this synonym as an OBO line to appear in a [Term] stanza."""
@@ -168,7 +158,7 @@ abbreviation = SynonymTypeDef(
168
158
  acronym = SynonymTypeDef(reference=Reference(prefix="omo", identifier="0003012", name="acronym"))
169
159
 
170
160
 
171
- ReferenceHint = Union[Reference, "Term", Tuple[str, str], str]
161
+ ReferenceHint = Union[Reference, "Term", tuple[str, str], str]
172
162
 
173
163
 
174
164
  def _ensure_ref(reference: ReferenceHint) -> Reference:
@@ -199,26 +189,26 @@ class Term(Referenced):
199
189
  definition: Optional[str] = None
200
190
 
201
191
  #: References to articles in which the term appears
202
- provenance: List[Reference] = field(default_factory=list)
192
+ provenance: list[Reference] = field(default_factory=list)
203
193
 
204
194
  #: Relationships defined by [Typedef] stanzas
205
- relationships: Dict[TypeDef, List[Reference]] = field(default_factory=lambda: defaultdict(list))
195
+ relationships: dict[TypeDef, list[Reference]] = field(default_factory=lambda: defaultdict(list))
206
196
 
207
197
  #: Properties, which are not defined with Typedef and have scalar values instead of references.
208
- properties: Dict[str, List[str]] = field(default_factory=lambda: defaultdict(list))
198
+ properties: dict[str, list[str]] = field(default_factory=lambda: defaultdict(list))
209
199
 
210
200
  #: Relationships with the default "is_a"
211
- parents: List[Reference] = field(default_factory=list)
201
+ parents: list[Reference] = field(default_factory=list)
212
202
 
213
203
  #: Synonyms of this term
214
- synonyms: List[Synonym] = field(default_factory=list)
204
+ synonyms: list[Synonym] = field(default_factory=list)
215
205
 
216
206
  #: Equivalent references
217
- xrefs: List[Reference] = field(default_factory=list)
218
- xref_types: List[Reference] = field(default_factory=list)
207
+ xrefs: list[Reference] = field(default_factory=list)
208
+ xref_types: list[Reference] = field(default_factory=list)
219
209
 
220
210
  #: Alternate Identifiers
221
- alt_ids: List[Reference] = field(default_factory=list)
211
+ alt_ids: list[Reference] = field(default_factory=list)
222
212
 
223
213
  #: The sub-namespace within the ontology
224
214
  namespace: Optional[str] = None
@@ -228,7 +218,7 @@ class Term(Referenced):
228
218
 
229
219
  type: Literal["Term", "Instance"] = "Term"
230
220
 
231
- def __hash__(self): # noqa: D105
221
+ def __hash__(self):
232
222
  return hash((self.__class__, self.prefix, self.identifier))
233
223
 
234
224
  @classmethod
@@ -321,7 +311,7 @@ class Term(Referenced):
321
311
  raise ValueError("can not append a collection of parents containing a null parent")
322
312
  self.parents.extend(references)
323
313
 
324
- def get_properties(self, prop) -> List[str]:
314
+ def get_properties(self, prop) -> list[str]:
325
315
  """Get properties from the given key."""
326
316
  return self.properties[prop]
327
317
 
@@ -343,7 +333,7 @@ class Term(Referenced):
343
333
  raise ValueError
344
334
  return r[0]
345
335
 
346
- def get_relationships(self, typedef: TypeDef) -> List[Reference]:
336
+ def get_relationships(self, typedef: TypeDef) -> list[Reference]:
347
337
  """Get relationships from the given type."""
348
338
  return self.relationships[typedef]
349
339
 
@@ -399,16 +389,17 @@ class Term(Referenced):
399
389
  self.properties[prop].append(value)
400
390
 
401
391
  def _definition_fp(self) -> str:
402
- assert self.definition is not None
392
+ if self.definition is None:
393
+ raise AssertionError
403
394
  return f'"{obo_escape_slim(self.definition)}" [{comma_separate(self.provenance)}]'
404
395
 
405
- def iterate_relations(self) -> Iterable[Tuple[TypeDef, Reference]]:
396
+ def iterate_relations(self) -> Iterable[tuple[TypeDef, Reference]]:
406
397
  """Iterate over pairs of typedefs and targets."""
407
398
  for typedef, targets in sorted(self.relationships.items(), key=_sort_relations):
408
399
  for target in sorted(targets, key=lambda ref: ref.preferred_curie):
409
400
  yield typedef, target
410
401
 
411
- def iterate_properties(self) -> Iterable[Tuple[str, str]]:
402
+ def iterate_properties(self) -> Iterable[tuple[str, str]]:
412
403
  """Iterate over pairs of property and values."""
413
404
  for prop, values in sorted(self.properties.items()):
414
405
  for value in sorted(values):
@@ -470,7 +461,7 @@ class Term(Referenced):
470
461
 
471
462
 
472
463
  #: A set of warnings, used to make sure we don't show the same one over and over
473
- _TYPEDEF_WARNINGS: Set[Tuple[str, str]] = set()
464
+ _TYPEDEF_WARNINGS: set[tuple[str, str]] = set()
474
465
 
475
466
 
476
467
  def _sort_relations(r):
@@ -489,6 +480,8 @@ def _sort_properties(r):
489
480
 
490
481
 
491
482
  class BioregistryError(ValueError):
483
+ """An error raised for non-canonical prefixes."""
484
+
492
485
  def __str__(self) -> str:
493
486
  return dedent(
494
487
  f"""
@@ -518,10 +511,10 @@ class Obo:
518
511
  format_version: ClassVar[str] = "1.2"
519
512
 
520
513
  #: Type definitions
521
- typedefs: ClassVar[Optional[List[TypeDef]]] = None
514
+ typedefs: ClassVar[Optional[list[TypeDef]]] = None
522
515
 
523
516
  #: Synonym type definitions
524
- synonym_typedefs: ClassVar[Optional[List[SynonymTypeDef]]] = None
517
+ synonym_typedefs: ClassVar[Optional[list[SynonymTypeDef]]] = None
525
518
 
526
519
  #: An annotation about how an ontology was generated
527
520
  auto_generated_by: ClassVar[Optional[str]] = None
@@ -541,7 +534,7 @@ class Obo:
541
534
  bioversions_key: ClassVar[Optional[str]] = None
542
535
 
543
536
  #: Root terms to use for the ontology
544
- root_terms: ClassVar[Optional[List[Reference]]] = None
537
+ root_terms: ClassVar[Optional[list[Reference]]] = None
545
538
 
546
539
  #: The date the ontology was generated
547
540
  date: Optional[datetime] = field(default_factory=datetime.today)
@@ -555,7 +548,7 @@ class Obo:
555
548
  #: The hierarchy of terms
556
549
  _hierarchy: Optional[nx.DiGraph] = field(init=False, default=None, repr=False)
557
550
  #: A cache of terms
558
- _items: Optional[List[Term]] = field(init=False, default=None, repr=False)
551
+ _items: Optional[list[Term]] = field(init=False, default=None, repr=False)
559
552
 
560
553
  term_sort_key: ClassVar[Optional[Callable[["Obo", Term], int]]] = None
561
554
 
@@ -590,7 +583,7 @@ class Obo:
590
583
  return get_version(self.bioversions_key)
591
584
  except KeyError:
592
585
  logger.warning(f"[{self.bioversions_key}] bioversions doesn't list this resource ")
593
- except IOError:
586
+ except OSError:
594
587
  logger.warning(f"[{self.bioversions_key}] error while looking up version")
595
588
  return None
596
589
 
@@ -661,13 +654,14 @@ class Obo:
661
654
  def iterate_obo_lines(self) -> Iterable[str]:
662
655
  """Iterate over the lines to write in an OBO file."""
663
656
  yield f"format-version: {self.format_version}"
664
- yield f"date: {self.date_formatted}"
665
657
 
666
658
  if self.auto_generated_by is not None:
667
659
  yield f"auto-generated-by: {self.auto_generated_by}"
668
660
 
669
661
  if self.data_version is not None:
670
662
  yield f"data-version: {self.data_version}"
663
+ else:
664
+ yield f"date: {self.date_formatted}"
671
665
 
672
666
  for prefix, url in sorted((self.idspaces or {}).items()):
673
667
  yield f"idspace: {prefix} {url}"
@@ -716,7 +710,7 @@ class Obo:
716
710
  @staticmethod
717
711
  def _write_lines(it, file: Optional[TextIO]):
718
712
  for line in it:
719
- print(line, file=file) # noqa: T201
713
+ print(line, file=file)
720
714
 
721
715
  def write_obonet_gz(self, path: Union[str, Path]) -> None:
722
716
  """Write the OBO to a gzipped dump in Obonet JSON."""
@@ -895,16 +889,16 @@ class Obo:
895
889
  self._items = sorted(self.iter_terms(force=self.force), key=key)
896
890
  return self._items
897
891
 
898
- def __iter__(self) -> Iterator["Term"]: # noqa: D105
892
+ def __iter__(self) -> Iterator["Term"]:
899
893
  if self.iter_only:
900
894
  return iter(self.iter_terms(force=self.force))
901
895
  return iter(self._items_accessor)
902
896
 
903
- def ancestors(self, identifier: str) -> Set[str]:
897
+ def ancestors(self, identifier: str) -> set[str]:
904
898
  """Return a set of identifiers for parents of the given identifier."""
905
899
  return nx.descendants(self.hierarchy, identifier) # note this is backwards
906
900
 
907
- def descendants(self, identifier: str) -> Set[str]:
901
+ def descendants(self, identifier: str) -> set[str]:
908
902
  """Return a set of identifiers for the children of the given identifier."""
909
903
  return nx.ancestors(self.hierarchy, identifier) # note this is backwards
910
904
 
@@ -914,11 +908,12 @@ class Obo:
914
908
  .. code-block:: python
915
909
 
916
910
  from pyobo import get_obo
917
- obo = get_obo('go')
918
911
 
919
- interleukin_10_complex = '1905571' # interleukin-10 receptor complex
920
- all_complexes = '0032991'
921
- assert obo.is_descendant('1905571', '0032991')
912
+ obo = get_obo("go")
913
+
914
+ interleukin_10_complex = "1905571" # interleukin-10 receptor complex
915
+ all_complexes = "0032991"
916
+ assert obo.is_descendant("1905571", "0032991")
922
917
  """
923
918
  return ancestor in self.ancestors(descendant)
924
919
 
@@ -931,11 +926,12 @@ class Obo:
931
926
  .. code-block:: python
932
927
 
933
928
  from pyobo import get_obo
934
- obo = get_obo('go')
935
929
 
936
- identifier = '1905571' # interleukin-10 receptor complex
937
- is_complex = '0032991' in nx.descendants(obo.hierarchy, identifier) # should be true
938
- """ # noqa:D401
930
+ obo = get_obo("go")
931
+
932
+ identifier = "1905571" # interleukin-10 receptor complex
933
+ is_complex = "0032991" in nx.descendants(obo.hierarchy, identifier) # should be true
934
+ """
939
935
  if self._hierarchy is None:
940
936
  self._hierarchy = nx.DiGraph()
941
937
  for term in self._iter_terms(desc=f"[{self.ontology}] getting hierarchy"):
@@ -1006,10 +1002,10 @@ class Obo:
1006
1002
 
1007
1003
  def get_metadata(self) -> Mapping[str, Any]:
1008
1004
  """Get metadata."""
1009
- return dict(
1010
- version=self.data_version,
1011
- date=self.date and self.date.isoformat(),
1012
- )
1005
+ return {
1006
+ "version": self.data_version,
1007
+ "date": self.date and self.date.isoformat(),
1008
+ }
1013
1009
 
1014
1010
  def iterate_ids(self, *, use_tqdm: bool = False) -> Iterable[str]:
1015
1011
  """Iterate over identifiers."""
@@ -1017,11 +1013,11 @@ class Obo:
1017
1013
  if term.prefix == self.ontology:
1018
1014
  yield term.identifier
1019
1015
 
1020
- def get_ids(self, *, use_tqdm: bool = False) -> Set[str]:
1016
+ def get_ids(self, *, use_tqdm: bool = False) -> set[str]:
1021
1017
  """Get the set of identifiers."""
1022
1018
  return set(self.iterate_ids(use_tqdm=use_tqdm))
1023
1019
 
1024
- def iterate_id_name(self, *, use_tqdm: bool = False) -> Iterable[Tuple[str, str]]:
1020
+ def iterate_id_name(self, *, use_tqdm: bool = False) -> Iterable[tuple[str, str]]:
1025
1021
  """Iterate identifier name pairs."""
1026
1022
  for term in self._iter_terms(use_tqdm=use_tqdm, desc=f"[{self.ontology}] getting names"):
1027
1023
  if term.prefix == self.ontology and term.name:
@@ -1031,19 +1027,23 @@ class Obo:
1031
1027
  """Get a mapping from identifiers to names."""
1032
1028
  return dict(self.iterate_id_name(use_tqdm=use_tqdm))
1033
1029
 
1034
- def iterate_id_definition(self, *, use_tqdm: bool = False) -> Iterable[Tuple[str, str]]:
1030
+ def iterate_id_definition(self, *, use_tqdm: bool = False) -> Iterable[tuple[str, str]]:
1035
1031
  """Iterate over pairs of terms' identifiers and their respective definitions."""
1036
1032
  for term in self._iter_terms(use_tqdm=use_tqdm, desc=f"[{self.ontology}] getting names"):
1037
1033
  if term.identifier and term.definition:
1038
- yield term.identifier, term.definition.strip('"').replace("\n", " ").replace(
1039
- "\t", " "
1040
- ).replace(" ", " ")
1034
+ yield (
1035
+ term.identifier,
1036
+ term.definition.strip('"')
1037
+ .replace("\n", " ")
1038
+ .replace("\t", " ")
1039
+ .replace(" ", " "),
1040
+ )
1041
1041
 
1042
1042
  def get_id_definition_mapping(self, *, use_tqdm: bool = False) -> Mapping[str, str]:
1043
1043
  """Get a mapping from identifiers to definitions."""
1044
1044
  return dict(self.iterate_id_definition(use_tqdm=use_tqdm))
1045
1045
 
1046
- def get_obsolete(self, *, use_tqdm: bool = False) -> Set[str]:
1046
+ def get_obsolete(self, *, use_tqdm: bool = False) -> set[str]:
1047
1047
  """Get the set of obsolete identifiers."""
1048
1048
  return {
1049
1049
  term.identifier
@@ -1059,7 +1059,7 @@ class Obo:
1059
1059
 
1060
1060
  def iterate_id_species(
1061
1061
  self, *, prefix: Optional[str] = None, use_tqdm: bool = False
1062
- ) -> Iterable[Tuple[str, str]]:
1062
+ ) -> Iterable[tuple[str, str]]:
1063
1063
  """Iterate over terms' identifiers and respective species (if available)."""
1064
1064
  if prefix is None:
1065
1065
  prefix = NCBITAXON_PREFIX
@@ -1086,7 +1086,7 @@ class Obo:
1086
1086
  ]
1087
1087
  return pd.DataFrame(rows, columns=["prefix", "identifier", "name"])
1088
1088
 
1089
- def iter_typedef_id_name(self) -> Iterable[Tuple[str, str]]:
1089
+ def iter_typedef_id_name(self) -> Iterable[tuple[str, str]]:
1090
1090
  """Iterate over typedefs' identifiers and their respective names."""
1091
1091
  for typedef in self.typedefs or []:
1092
1092
  yield typedef.identifier, typedef.name
@@ -1099,7 +1099,7 @@ class Obo:
1099
1099
  # PROPS #
1100
1100
  #########
1101
1101
 
1102
- def iterate_properties(self, *, use_tqdm: bool = False) -> Iterable[Tuple[Term, str, str]]:
1102
+ def iterate_properties(self, *, use_tqdm: bool = False) -> Iterable[tuple[Term, str, str]]:
1103
1103
  """Iterate over tuples of terms, properties, and their values."""
1104
1104
  # TODO if property_prefix is set, try removing that as a prefix from all prop strings.
1105
1105
  for term in self._iter_terms(
@@ -1110,10 +1110,10 @@ class Obo:
1110
1110
 
1111
1111
  @property
1112
1112
  def properties_header(self):
1113
- """Property dataframe header.""" # noqa:D401
1113
+ """Property dataframe header."""
1114
1114
  return [f"{self.ontology}_id", "property", "value"]
1115
1115
 
1116
- def iter_property_rows(self, *, use_tqdm: bool = False) -> Iterable[Tuple[str, str, str]]:
1116
+ def iter_property_rows(self, *, use_tqdm: bool = False) -> Iterable[tuple[str, str, str]]:
1117
1117
  """Iterate property rows."""
1118
1118
  for term, prop, value in self.iterate_properties(use_tqdm=use_tqdm):
1119
1119
  yield term.identifier, prop, value
@@ -1127,7 +1127,7 @@ class Obo:
1127
1127
 
1128
1128
  def iterate_filtered_properties(
1129
1129
  self, prop: str, *, use_tqdm: bool = False
1130
- ) -> Iterable[Tuple[Term, str]]:
1130
+ ) -> Iterable[tuple[Term, str]]:
1131
1131
  """Iterate over tuples of terms and the values for the given property."""
1132
1132
  for term in self._iter_terms(use_tqdm=use_tqdm):
1133
1133
  for _prop, value in term.iterate_properties():
@@ -1155,7 +1155,7 @@ class Obo:
1155
1155
 
1156
1156
  def get_filtered_properties_multimapping(
1157
1157
  self, prop: str, *, use_tqdm: bool = False
1158
- ) -> Mapping[str, List[str]]:
1158
+ ) -> Mapping[str, list[str]]:
1159
1159
  """Get a mapping from a term's identifier to the property values."""
1160
1160
  return multidict(
1161
1161
  (term.identifier, value)
@@ -1168,7 +1168,7 @@ class Obo:
1168
1168
 
1169
1169
  def iterate_relations(
1170
1170
  self, *, use_tqdm: bool = False
1171
- ) -> Iterable[Tuple[Term, TypeDef, Reference]]:
1171
+ ) -> Iterable[tuple[Term, TypeDef, Reference]]:
1172
1172
  """Iterate over tuples of terms, relations, and their targets."""
1173
1173
  for term in self._iter_terms(
1174
1174
  use_tqdm=use_tqdm, desc=f"[{self.ontology}] getting relations"
@@ -1185,17 +1185,23 @@ class Obo:
1185
1185
 
1186
1186
  def iter_relation_rows(
1187
1187
  self, use_tqdm: bool = False
1188
- ) -> Iterable[Tuple[str, str, str, str, str]]:
1188
+ ) -> Iterable[tuple[str, str, str, str, str]]:
1189
1189
  """Iterate the relations' rows."""
1190
1190
  for term, typedef, reference in self.iterate_relations(use_tqdm=use_tqdm):
1191
- yield term.identifier, typedef.prefix, typedef.identifier, reference.prefix, reference.identifier
1191
+ yield (
1192
+ term.identifier,
1193
+ typedef.prefix,
1194
+ typedef.identifier,
1195
+ reference.prefix,
1196
+ reference.identifier,
1197
+ )
1192
1198
 
1193
1199
  def iterate_filtered_relations(
1194
1200
  self,
1195
1201
  relation: RelationHint,
1196
1202
  *,
1197
1203
  use_tqdm: bool = False,
1198
- ) -> Iterable[Tuple[Term, Reference]]:
1204
+ ) -> Iterable[tuple[Term, Reference]]:
1199
1205
  """Iterate over tuples of terms and ther targets for the given relation."""
1200
1206
  _target_prefix, _target_identifier = get_reference_tuple(relation)
1201
1207
  for term, typedef, reference in self.iterate_relations(use_tqdm=use_tqdm):
@@ -1204,7 +1210,7 @@ class Obo:
1204
1210
 
1205
1211
  @property
1206
1212
  def relations_header(self) -> Sequence[str]:
1207
- """Header for the relations dataframe.""" # noqa:D401
1213
+ """Header for the relations dataframe."""
1208
1214
  return [f"{self.ontology}_id", RELATION_PREFIX, RELATION_ID, TARGET_PREFIX, TARGET_ID]
1209
1215
 
1210
1216
  def get_relations_df(self, *, use_tqdm: bool = False) -> pd.DataFrame:
@@ -1235,7 +1241,7 @@ class Obo:
1235
1241
  target_prefix: str,
1236
1242
  *,
1237
1243
  use_tqdm: bool = False,
1238
- ) -> Iterable[Tuple[Term, Reference]]:
1244
+ ) -> Iterable[tuple[Term, Reference]]:
1239
1245
  """Iterate over relationships between one identifier and another."""
1240
1246
  for term, reference in self.iterate_filtered_relations(
1241
1247
  relation=relation, use_tqdm=use_tqdm
@@ -1258,9 +1264,9 @@ class Obo:
1258
1264
 
1259
1265
  >>> from pyobo.sources.hgnc import get_obo
1260
1266
  >>> obo = get_obo()
1261
- >>> human_mapt_hgnc_id = '6893'
1262
- >>> mouse_mapt_mgi_id = '97180'
1263
- >>> hgnc_mgi_orthology_mapping = obo.get_relation_mapping('ro:HOM0000017', 'mgi')
1267
+ >>> human_mapt_hgnc_id = "6893"
1268
+ >>> mouse_mapt_mgi_id = "97180"
1269
+ >>> hgnc_mgi_orthology_mapping = obo.get_relation_mapping("ro:HOM0000017", "mgi")
1264
1270
  >>> assert mouse_mapt_mgi_id == hgnc_mgi_orthology_mapping[human_mapt_hgnc_id]
1265
1271
  """
1266
1272
  return {
@@ -1284,9 +1290,9 @@ class Obo:
1284
1290
 
1285
1291
  >>> from pyobo.sources.hgnc import get_obo
1286
1292
  >>> obo = get_obo()
1287
- >>> human_mapt_hgnc_id = '6893'
1288
- >>> mouse_mapt_mgi_id = '97180'
1289
- >>> assert mouse_mapt_mgi_id == obo.get_relation(human_mapt_hgnc_id, 'ro:HOM0000017', 'mgi')
1293
+ >>> human_mapt_hgnc_id = "6893"
1294
+ >>> mouse_mapt_mgi_id = "97180"
1295
+ >>> assert mouse_mapt_mgi_id == obo.get_relation(human_mapt_hgnc_id, "ro:HOM0000017", "mgi")
1290
1296
  """
1291
1297
  relation_mapping = self.get_relation_mapping(
1292
1298
  relation=relation, target_prefix=target_prefix, use_tqdm=use_tqdm
@@ -1299,7 +1305,7 @@ class Obo:
1299
1305
  target_prefix: str,
1300
1306
  *,
1301
1307
  use_tqdm: bool = False,
1302
- ) -> Mapping[str, List[str]]:
1308
+ ) -> Mapping[str, list[str]]:
1303
1309
  """Get a mapping from the term's identifier to the target's identifiers."""
1304
1310
  return multidict(
1305
1311
  (term.identifier, reference.identifier)
@@ -1315,7 +1321,7 @@ class Obo:
1315
1321
  typedef: TypeDef,
1316
1322
  *,
1317
1323
  use_tqdm: bool = False,
1318
- ) -> Mapping[str, List[Reference]]:
1324
+ ) -> Mapping[str, list[Reference]]:
1319
1325
  """Get a mapping from identifiers to a list of all references for the given relation."""
1320
1326
  return multidict(
1321
1327
  (term.identifier, reference)
@@ -1329,18 +1335,18 @@ class Obo:
1329
1335
  # SYNONYMS #
1330
1336
  ############
1331
1337
 
1332
- def iterate_synonyms(self, *, use_tqdm: bool = False) -> Iterable[Tuple[Term, Synonym]]:
1338
+ def iterate_synonyms(self, *, use_tqdm: bool = False) -> Iterable[tuple[Term, Synonym]]:
1333
1339
  """Iterate over pairs of term and synonym object."""
1334
1340
  for term in self._iter_terms(use_tqdm=use_tqdm, desc=f"[{self.ontology}] getting synonyms"):
1335
1341
  for synonym in sorted(term.synonyms, key=attrgetter("name")):
1336
1342
  yield term, synonym
1337
1343
 
1338
- def iterate_synonym_rows(self, *, use_tqdm: bool = False) -> Iterable[Tuple[str, str]]:
1344
+ def iterate_synonym_rows(self, *, use_tqdm: bool = False) -> Iterable[tuple[str, str]]:
1339
1345
  """Iterate over pairs of identifier and synonym text."""
1340
1346
  for term, synonym in self.iterate_synonyms(use_tqdm=use_tqdm):
1341
1347
  yield term.identifier, synonym.name
1342
1348
 
1343
- def get_id_synonyms_mapping(self, *, use_tqdm: bool = False) -> Mapping[str, List[str]]:
1349
+ def get_id_synonyms_mapping(self, *, use_tqdm: bool = False) -> Mapping[str, list[str]]:
1344
1350
  """Get a mapping from identifiers to a list of sorted synonym strings."""
1345
1351
  return multidict(self.iterate_synonym_rows(use_tqdm=use_tqdm))
1346
1352
 
@@ -1348,7 +1354,7 @@ class Obo:
1348
1354
  # XREFS #
1349
1355
  #########
1350
1356
 
1351
- def iterate_xrefs(self, *, use_tqdm: bool = False) -> Iterable[Tuple[Term, Reference]]:
1357
+ def iterate_xrefs(self, *, use_tqdm: bool = False) -> Iterable[tuple[Term, Reference]]:
1352
1358
  """Iterate over xrefs."""
1353
1359
  for term in self._iter_terms(use_tqdm=use_tqdm, desc=f"[{self.ontology}] getting xrefs"):
1354
1360
  for xref in term.xrefs:
@@ -1356,20 +1362,20 @@ class Obo:
1356
1362
 
1357
1363
  def iterate_filtered_xrefs(
1358
1364
  self, prefix: str, *, use_tqdm: bool = False
1359
- ) -> Iterable[Tuple[Term, Reference]]:
1365
+ ) -> Iterable[tuple[Term, Reference]]:
1360
1366
  """Iterate over xrefs to a given prefix."""
1361
1367
  for term, xref in self.iterate_xrefs(use_tqdm=use_tqdm):
1362
1368
  if xref.prefix == prefix:
1363
1369
  yield term, xref
1364
1370
 
1365
- def iterate_xref_rows(self, *, use_tqdm: bool = False) -> Iterable[Tuple[str, str, str]]:
1371
+ def iterate_xref_rows(self, *, use_tqdm: bool = False) -> Iterable[tuple[str, str, str]]:
1366
1372
  """Iterate over terms' identifiers, xref prefixes, and xref identifiers."""
1367
1373
  for term, xref in self.iterate_xrefs(use_tqdm=use_tqdm):
1368
1374
  yield term.identifier, xref.prefix, xref.identifier
1369
1375
 
1370
1376
  @property
1371
1377
  def xrefs_header(self):
1372
- """The header for the xref dataframe.""" # noqa:D401
1378
+ """The header for the xref dataframe."""
1373
1379
  return [f"{self.ontology}_id", TARGET_PREFIX, TARGET_ID]
1374
1380
 
1375
1381
  def get_xrefs_df(self, *, use_tqdm: bool = False) -> pd.DataFrame:
@@ -1390,7 +1396,7 @@ class Obo:
1390
1396
 
1391
1397
  def get_filtered_multixrefs_mapping(
1392
1398
  self, prefix: str, *, use_tqdm: bool = False
1393
- ) -> Mapping[str, List[str]]:
1399
+ ) -> Mapping[str, list[str]]:
1394
1400
  """Get filtered xrefs as a dictionary."""
1395
1401
  return multidict(
1396
1402
  (term.identifier, xref.identifier)
@@ -1401,18 +1407,18 @@ class Obo:
1401
1407
  # ALTS #
1402
1408
  ########
1403
1409
 
1404
- def iterate_alts(self) -> Iterable[Tuple[Term, Reference]]:
1410
+ def iterate_alts(self) -> Iterable[tuple[Term, Reference]]:
1405
1411
  """Iterate over alternative identifiers."""
1406
1412
  for term in self:
1407
1413
  for alt in term.alt_ids:
1408
1414
  yield term, alt
1409
1415
 
1410
- def iterate_alt_rows(self) -> Iterable[Tuple[str, str]]:
1416
+ def iterate_alt_rows(self) -> Iterable[tuple[str, str]]:
1411
1417
  """Iterate over pairs of terms' primary identifiers and alternate identifiers."""
1412
1418
  for term, alt in self.iterate_alts():
1413
1419
  yield term.identifier, alt.identifier
1414
1420
 
1415
- def get_id_alts_mapping(self) -> Mapping[str, List[str]]:
1421
+ def get_id_alts_mapping(self) -> Mapping[str, list[str]]:
1416
1422
  """Get a mapping from identifiers to a list of alternative identifiers."""
1417
1423
  return multidict((term.identifier, alt.identifier) for term, alt in self.iterate_alts())
1418
1424
 
@@ -1422,14 +1428,14 @@ def make_ad_hoc_ontology(
1422
1428
  _name: str,
1423
1429
  _auto_generated_by: Optional[str] = None,
1424
1430
  _format_version: str = "1.2",
1425
- _typedefs: Optional[List[TypeDef]] = None,
1426
- _synonym_typedefs: Optional[List[SynonymTypeDef]] = None,
1431
+ _typedefs: Optional[list[TypeDef]] = None,
1432
+ _synonym_typedefs: Optional[list[SynonymTypeDef]] = None,
1427
1433
  _date: Optional[datetime] = None,
1428
1434
  _data_version: Optional[str] = None,
1429
1435
  _idspaces: Optional[Mapping[str, str]] = None,
1430
- _root_terms: Optional[List[Reference]] = None,
1436
+ _root_terms: Optional[list[Reference]] = None,
1431
1437
  *,
1432
- terms: List[Term],
1438
+ terms: list[Term],
1433
1439
  ) -> "Obo":
1434
1440
  """Make an ad-hoc ontology."""
1435
1441
 
@@ -1456,7 +1462,7 @@ def make_ad_hoc_ontology(
1456
1462
  return AdHocOntology()
1457
1463
 
1458
1464
 
1459
- def _convert_typedefs(typedefs: Optional[Iterable[TypeDef]]) -> List[Mapping[str, Any]]:
1465
+ def _convert_typedefs(typedefs: Optional[Iterable[TypeDef]]) -> list[Mapping[str, Any]]:
1460
1466
  """Convert the type defs."""
1461
1467
  if not typedefs:
1462
1468
  return []
@@ -1466,10 +1472,10 @@ def _convert_typedefs(typedefs: Optional[Iterable[TypeDef]]) -> List[Mapping[str
1466
1472
  def _convert_typedef(typedef: TypeDef) -> Mapping[str, Any]:
1467
1473
  """Convert a type def."""
1468
1474
  # TODO add more later
1469
- return typedef.reference.dict()
1475
+ return typedef.reference.model_dump()
1470
1476
 
1471
1477
 
1472
- def _convert_synonym_typedefs(synonym_typedefs: Optional[Iterable[SynonymTypeDef]]) -> List[str]:
1478
+ def _convert_synonym_typedefs(synonym_typedefs: Optional[Iterable[SynonymTypeDef]]) -> list[str]:
1473
1479
  """Convert the synonym type defs."""
1474
1480
  if not synonym_typedefs:
1475
1481
  return []
pyobo/struct/typedef.py CHANGED
@@ -1,9 +1,8 @@
1
- # -*- coding: utf-8 -*-
2
-
3
1
  """Default typedefs, references, and other structures."""
4
2
 
3
+ from collections.abc import Iterable
5
4
  from dataclasses import dataclass, field
6
- from typing import Dict, Iterable, List, Optional, Tuple, Union
5
+ from typing import Optional, Union
7
6
 
8
7
  from .reference import Reference, Referenced
9
8
  from ..identifier_utils import normalize_curie
@@ -71,11 +70,11 @@ class TypeDef(Referenced):
71
70
  is_symmetric: Optional[bool] = None
72
71
  domain: Optional[Reference] = None
73
72
  range: Optional[Reference] = None
74
- parents: List[Reference] = field(default_factory=list)
75
- xrefs: List[Reference] = field(default_factory=list)
73
+ parents: list[Reference] = field(default_factory=list)
74
+ xrefs: list[Reference] = field(default_factory=list)
76
75
  inverse: Optional[Reference] = None
77
76
  created_by: Optional[str] = None
78
- holds_over_chain: Optional[List[Reference]] = None
77
+ holds_over_chain: Optional[list[Reference]] = None
79
78
  #: Whether this relationship is a metadata tag. Properties that are marked as metadata tags are
80
79
  #: used to record object metadata. Object metadata is additional information about an object
81
80
  #: that is useful to track, but does not impact the definition of the object or how it should
@@ -83,7 +82,7 @@ class TypeDef(Referenced):
83
82
  #: structured notes about a term, for example.
84
83
  is_metadata_tag: Optional[bool] = None
85
84
 
86
- def __hash__(self) -> int: # noqa: D105
85
+ def __hash__(self) -> int:
87
86
  return hash((self.__class__, self.prefix, self.identifier))
88
87
 
89
88
  def iterate_obo_lines(self) -> Iterable[str]:
@@ -140,10 +139,10 @@ class TypeDef(Referenced):
140
139
  return cls.from_triple(prefix=prefix, identifier=identifier, name=name)
141
140
 
142
141
 
143
- RelationHint = Union[Reference, TypeDef, Tuple[str, str], str]
142
+ RelationHint = Union[Reference, TypeDef, tuple[str, str], str]
144
143
 
145
144
 
146
- def get_reference_tuple(relation: RelationHint) -> Tuple[str, str]:
145
+ def get_reference_tuple(relation: RelationHint) -> tuple[str, str]:
147
146
  """Get tuple for typedef/reference."""
148
147
  if isinstance(relation, (Reference, TypeDef)):
149
148
  return relation.prefix, relation.identifier
@@ -366,7 +365,7 @@ has_homepage = TypeDef(
366
365
  reference=Reference(prefix="foaf", identifier="homepage", name="homepage"), is_metadata_tag=True
367
366
  )
368
367
 
369
- default_typedefs: Dict[Tuple[str, str], TypeDef] = {
368
+ default_typedefs: dict[tuple[str, str], TypeDef] = {
370
369
  v.pair: v for k, v in locals().items() if isinstance(v, TypeDef)
371
370
  }
372
371
 
pyobo/struct/utils.py CHANGED
@@ -1,5 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
-
3
1
  """Utilities for data structures for OBO."""
4
2
 
5
3
  __all__ = [
pyobo/utils/__init__.py CHANGED
@@ -1,3 +1 @@
1
- # -*- coding: utf-8 -*-
2
-
3
1
  """Utilities."""