diff --git a/sbol3/toplevel.py b/sbol3/toplevel.py index 49c5917..4ceeb7d 100644 --- a/sbol3/toplevel.py +++ b/sbol3/toplevel.py @@ -6,6 +6,11 @@ class TopLevel(Identified): def __init__(self, identity: str, type_uri: str) -> None: + # Sanity check identity, which is required for a TopLevel + # More checking on identity happens in Identified, but Identified + # does not require an identity, only TopLevel does. + if not identity or not isinstance(identity, str): + raise ValueError('Identity must be a non-empty string') super().__init__(identity, type_uri) self.attachments = ReferencedObject(self, SBOL_HAS_ATTACHMENT, 0, math.inf) diff --git a/test/test_custom.py b/test/test_custom.py index cab29e0..57f9311 100644 --- a/test/test_custom.py +++ b/test/test_custom.py @@ -79,6 +79,17 @@ def test_round_trip(self): # Compare specially self.assertCountEqual([True, False], obj2.foo_bool) + def test_none_identity(self): + # Make sure a ValueError is raised if None is passed + # as a CustomTopLevel identity. And also if identity + # is an empty string or not a string. + with self.assertRaises(ValueError): + obj = CustomTopClass(None) + with self.assertRaises(ValueError): + obj = CustomTopClass('') + with self.assertRaises(ValueError): + obj = CustomTopClass(3) + class TestCustomIdentified(unittest.TestCase):