Skip to content

Commit

Permalink
Merge pull request #60 from khaeru/feature/get-anno
Browse files Browse the repository at this point in the history
Add AnnotableArtefact.get_annotation() and test
  • Loading branch information
khaeru committed Feb 26, 2021
2 parents a4c2e9a + 377d8fc commit 9507e1d
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 0 deletions.
1 change: 1 addition & 0 deletions doc/whatsnew.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ What's new?
Next release
============

- New convenience method :meth:`.AnnotableArtefact.get_annotation` to return but not remove an Annotation, e.g. by its ID (:pull:`60`).
- Add :file:`py.typed` to support type checking (e.g. with `mypy <https://mypy.readthedocs.io>`_) in packages that depend on :mod:`sdmx`.

v2.1.0 (2021-02-22)
Expand Down
16 changes: 16 additions & 0 deletions sdmx/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,22 @@ class AnnotableArtefact(BaseModel):
#: feature.
annotations: List[Annotation] = []

def get_annotation(self, **attrib):
"""Return a :class:`Annotation` with given `attrib`, e.g. 'id'.
If more than one `attrib` is given, all must match a particular annotation.
Raises
------
KeyError
If there is no matching annotation.
"""
for anno in self.annotations:
if all(getattr(anno, key, None) == value for key, value in attrib.items()):
return anno

raise KeyError(attrib)

def pop_annotation(self, **attrib):
"""Remove and return a :class:`Annotation` with given `attrib`, e.g. 'id'.
Expand Down
20 changes: 20 additions & 0 deletions sdmx/tests/test_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,26 @@


class TestAnnotableArtefact:
def test_get_annotation(self):
aa = model.AnnotableArtefact(
annotations=[
model.Annotation(id="foo", text="bar"),
model.Annotation(id="baz", title="baz_title", text="baz_text"),
]
)

with pytest.raises(KeyError):
aa.get_annotation(id="bar")

# Retrieve with 1 key
assert "bar" == str(aa.get_annotation(id="foo").text)

# Retrieve with 2 keys
assert "baz_text" == str(aa.get_annotation(id="baz", title="baz_title").text)

# Annotations are not removed
assert 2 == len(aa.annotations)

def test_pop_annotation(self):
aa = model.AnnotableArtefact()
anno = model.Annotation(id="foo", text="bar")
Expand Down

0 comments on commit 9507e1d

Please sign in to comment.