diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index eef084f5..266977e4 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -5,9 +5,11 @@
+
-
+
+
@@ -203,6 +205,8 @@
"Python tests.pytest for test_formula.TestFormula.test_formula.executor": "Run",
"Python tests.pytest for test_greek.TestGreekAlphabetLowercaseSerifItalic.test_greek_alphabet_lowercase_serif_italic.executor": "Run",
"Python tests.pytest for test_greek_alphabet_uppercase_serif_italic.TestGreekAlphabetLowercaseSerifItalic.test_greek_alphabet_lowercase_serif_italic.executor": "Run",
+ "Python tests.pytest for test_identifiers.TestIdentifiers.test_slug.executor": "Run",
+ "Python tests.pytest for test_identifiers.TestSlug.test_identifier.executor": "Run",
"Python tests.pytest for test_inference_rules_1.TestAdjunction.test_adjunction.executor": "Run",
"Python tests.pytest for test_inference_rules_1.TestModusPonens.executor": "Run",
"Python tests.pytest for test_inference_rules_1.TestModusPonens.test_modus_ponens.executor": "Run",
@@ -305,6 +309,7 @@
"Python tests.pytest in test_fl1.py.executor": "Run",
"Python tests.pytest in test_greek_alphabet_lowercase_serif_italic.py.executor": "Run",
"Python tests.pytest in test_greek_alphabet_uppercase_serif_italic.py.executor": "Run",
+ "Python tests.pytest in test_identifiers.py.executor": "Run",
"Python tests.pytest in test_inference_rules_1.py.executor": "Run",
"Python tests.pytest in test_interpretation.py.executor": "Run",
"Python tests.pytest in test_minimal_logic_1.py.executor": "Run",
@@ -421,7 +426,7 @@
-
+
@@ -628,7 +633,7 @@
-
+
@@ -641,28 +646,28 @@
-
+
-
+
-
+
-
-
+
+
-
+
@@ -675,28 +680,28 @@
-
-
+
+
-
+
-
+
-
+
-
+
@@ -709,11 +714,11 @@
-
+
-
+
@@ -726,7 +731,7 @@
-
+
@@ -758,10 +763,10 @@
+
+
-
-
-
+
@@ -769,11 +774,11 @@
+
+
+
-
-
-
@@ -793,14 +798,6 @@
1687980987309
-
-
- 1732462201620
-
-
-
- 1732462201620
-
1732470978419
@@ -1185,7 +1182,15 @@
1733693312501
-
+
+
+ 1733693460844
+
+
+
+ 1733693460844
+
+
random
@@ -1342,9 +1347,9 @@
- file://$PROJECT_DIR$/src/punctilious/_presentation.py
- 79
-
+ file://$PROJECT_DIR$/tests/test_identifiers.py
+ 32
+
diff --git a/src/punctilious/__init__.py b/src/punctilious/__init__.py
index ad93cfb8..2964ef0f 100644
--- a/src/punctilious/__init__.py
+++ b/src/punctilious/__init__.py
@@ -1,5 +1,7 @@
import _util
from _util import get_yaml_from_package
+import _identifiers
+from _identifiers import ensure_identifier, ensure_slug, FlexibleSlug, FlexibleUUID, Identifier, Slug, SlugsDictionary
import _presentation
from _presentation import Representation, ensure_representations, ensure_representation, latex_math, Tag, \
TagsPreferences, \
diff --git a/src/punctilious/__pycache__/__init__.cpython-312.pyc b/src/punctilious/__pycache__/__init__.cpython-312.pyc
index 29ef5fab..668ad3ed 100644
Binary files a/src/punctilious/__pycache__/__init__.cpython-312.pyc and b/src/punctilious/__pycache__/__init__.cpython-312.pyc differ
diff --git a/src/punctilious/__pycache__/_foundations.cpython-312.pyc b/src/punctilious/__pycache__/_foundations.cpython-312.pyc
index 696f63b7..4627b700 100644
Binary files a/src/punctilious/__pycache__/_foundations.cpython-312.pyc and b/src/punctilious/__pycache__/_foundations.cpython-312.pyc differ
diff --git a/src/punctilious/__pycache__/_identifiers.cpython-312.pyc b/src/punctilious/__pycache__/_identifiers.cpython-312.pyc
index 4298a7c5..8ee0b57b 100644
Binary files a/src/punctilious/__pycache__/_identifiers.cpython-312.pyc and b/src/punctilious/__pycache__/_identifiers.cpython-312.pyc differ
diff --git a/src/punctilious/_foundations.py b/src/punctilious/_foundations.py
index 73bba6c4..21326fa6 100644
--- a/src/punctilious/_foundations.py
+++ b/src/punctilious/_foundations.py
@@ -31,7 +31,7 @@ def __init__(self, c, a=None):
:param c: A connector.
:param args: A (possibly empty) collection of arguments.
"""
- pass
+ super().__init__()
def __new__(cls, c, a=None):
c = ensure_connector(c)
diff --git a/src/punctilious/_identifiers.py b/src/punctilious/_identifiers.py
index 22c55fbc..813fc4de 100644
--- a/src/punctilious/_identifiers.py
+++ b/src/punctilious/_identifiers.py
@@ -11,7 +11,7 @@ def __eq__(self, other):
return hash(self) == hash(other)
def __hash__(self):
- return hash((self.__class__, str(self),))
+ return hash((self.__class__, super().__str__(),))
def __init__(self, slug: str):
super().__init__()
@@ -23,10 +23,10 @@ def __new__(cls, slug: str):
return super().__new__(cls, slug)
def __repr__(self):
- return f'"{str(super())}" slug'
+ return f'"{str(super().__str__())}" slug'
def __str__(self):
- return str(super())
+ return str(super().__str__())
class SlugsDictionary(dict):
@@ -88,11 +88,7 @@ def __init__(self, i: FlexibleUUID, p: FlexibleSlug, s: FlexibleSlug):
:param p: A package slug.
:param s: An object slug.
"""
- i = ensure_uuid(i)
- p = ensure_slug(p)
- s = ensure_slug(s)
- phi = (i, p, s,)
- super().__init__(phi)
+ super().__init__()
def __new__(cls, i: FlexibleUUID, p: FlexibleSlug, s: FlexibleSlug):
i = ensure_uuid(i)
@@ -106,7 +102,7 @@ def __repr__(self):
:return:
"""
- return f'{self[0]}.{self[2]} ({self[1]}) identifier'
+ return f'"{self[1]}.{self[2]}" ({self[0]}) identifier'
def __str__(self):
"""A friendly representation of the identifier.
@@ -126,3 +122,15 @@ def package_uuid(self) -> uuid.UUID:
@property
def slug(self) -> Slug:
return self[2]
+
+
+FlexibleIdentifier = typing.Union[Identifier]
+
+
+def ensure_identifier(o: Identifier | str) -> Identifier:
+ """Assure `o` is of type Identifier, or implicitly convert `o` to Identifier, or raise an error if this fails.
+ """
+ if isinstance(o, Identifier):
+ return o
+ else:
+ raise ValueError(f'Invalid identifier {o}')
diff --git a/tests/__pycache__/test_identifiers.cpython-312-pytest-8.3.2.pyc b/tests/__pycache__/test_identifiers.cpython-312-pytest-8.3.2.pyc
new file mode 100644
index 00000000..985ebdf7
Binary files /dev/null and b/tests/__pycache__/test_identifiers.cpython-312-pytest-8.3.2.pyc differ
diff --git a/tests/test_identifiers.py b/tests/test_identifiers.py
new file mode 100644
index 00000000..6d4637fe
--- /dev/null
+++ b/tests/test_identifiers.py
@@ -0,0 +1,36 @@
+import pytest
+import punctilious as pu
+import uuid
+from test_shared_library import create_atomic_connector, create_function
+
+
+class TestSlug:
+ def test_slug(self):
+ """Test of representation with multiple string-constant renderers.
+ """
+
+ s1 = pu.Slug("foo")
+ s2 = pu.Slug("bar")
+ s3 = pu.Slug("foo")
+ assert s1 != s2
+ assert s1 == s3
+
+ def test_identifier(self):
+ uuid1 = uuid.uuid4()
+ uuid2 = uuid.uuid4()
+ foo = pu.Slug('foo')
+ bar = pu.Slug('bar')
+ taz = pu.Slug('taz')
+ i1 = pu.Identifier(uuid1, foo, bar)
+ i2 = pu.Identifier(uuid2, foo, bar)
+ i3 = pu.Identifier(uuid1, foo, bar)
+ i4 = pu.Identifier(uuid1, foo, taz)
+ print(hash(i1))
+ print(hash(i4))
+ assert i1.package_slug == pu.Slug('foo')
+ assert i1.package_uuid == uuid1
+ assert i1.slug == pu.Slug('bar')
+ assert i4.slug == pu.Slug('taz')
+ assert i1 != i2
+ assert i1 == i3
+ assert i1 != i4