diff --git a/doc/whatsnew.rst b/doc/whatsnew.rst index 03c524249..2a0be1c91 100644 --- a/doc/whatsnew.rst +++ b/doc/whatsnew.rst @@ -3,8 +3,10 @@ What's new? *********** -.. Next release -.. ============ +Next release +============ + +- Bugfix: in v2.19.0 (only), :py:`IdentifableArtefact(id="")` resulted in the given ID (an empty :class:`str`) being incorrectly replaced with :data:`~.common.MissingID` (:pull:`203`). v2.19.0 (2024-10-23) ==================== diff --git a/sdmx/model/common.py b/sdmx/model/common.py index f0cad7177..79a527277 100644 --- a/sdmx/model/common.py +++ b/sdmx/model/common.py @@ -146,6 +146,7 @@ def __eq__(self, other): return isinstance(other, self.__class__) +#: Singleton used for :attr:`.IdentifiableArtefact.id` if none given. MissingID = _MissingID() @@ -245,7 +246,8 @@ def __post_init__(self): # Validate URN, if any self._urn = URN(self.urn) - if not self.id: + if self.id is MissingID: + # Try to retrieve an item ID from the URN, if any self.id = self._urn.item_id or self._urn.id or MissingID elif self.urn and self.id not in (self._urn.item_id or self._urn.id): # Ensure explicit ID is consistent with URN diff --git a/sdmx/tests/model/test_common.py b/sdmx/tests/model/test_common.py index 775ed73e1..680fee4bf 100644 --- a/sdmx/tests/model/test_common.py +++ b/sdmx/tests/model/test_common.py @@ -93,6 +93,17 @@ def test_eval_annotation(self, caplog) -> None: class TestIdentifiableArtefact: + def test_init_empty_id(self): + """IdentifiableArtefact can be initialized with an empty :class:`str` as ID.""" + # No id= parameter → id attribute is MissingID + ia0 = IdentifiableArtefact() + assert common.MissingID == ia0.id + assert common.MissingID is ia0.id + + # Empty string parameter → id attribute is empty string + ia1 = IdentifiableArtefact(id="") + assert "" == ia1.id + def test_init_urn(self): """IdentifiableArtefact can be initialized with URN.""" ia = IdentifiableArtefact(urn=URN)