add support for plain_data __repr__ with fields that aren't set
authorJacob Lifshay <programmerjake@gmail.com>
Tue, 16 Aug 2022 06:07:40 +0000 (23:07 -0700)
committerJacob Lifshay <programmerjake@gmail.com>
Tue, 16 Aug 2022 06:07:40 +0000 (23:07 -0700)
src/nmutil/plain_data.py
src/nmutil/test/test_plain_data.py

index 1c170a4d28d0384e93321ad4c4a1ff2ad2770549..ace4d61a890f1b80cfbd2bc11288715ca650fd35 100644 (file)
@@ -5,6 +5,16 @@ class FrozenPlainDataError(AttributeError):
     pass
 
 
+class __NotSet:
+    """ helper for __repr__ for when fields aren't set """
+
+    def __repr__(self):
+        return "<not set>"
+
+
+__NOT_SET = __NotSet()
+
+
 def _decorator(cls, *, eq, unsafe_hash, order, repr_, frozen):
     if not isinstance(cls, type):
         raise TypeError(
@@ -175,7 +185,7 @@ def _decorator(cls, *, eq, unsafe_hash, order, repr_, frozen):
         def __repr__(self):
             parts = []
             for name in fields:
-                parts.append(f"{name}={getattr(self, name)!r}")
+                parts.append(f"{name}={getattr(self, name, __NOT_SET)!r}")
             return f"{self.__class__.__qualname__}({', '.join(parts)})"
 
         add_method_or_error(__repr__)
index 6952fe1ff1ca9a52eb14770db4fa8ee4b7406db5..a087e6e5b04f7f05e6f74c911a9dfb9b79b7eea0 100644 (file)
@@ -58,6 +58,15 @@ class PlainDataF2(PlainDataF1):
         self.z = z
 
 
+@plain_data()
+class UnsetField:
+    __slots__ = "a", "b"
+
+    def __init__(self, **kwargs):
+        for name, value in kwargs.items():
+            setattr(self, name, value)
+
+
 class TestPlainData(unittest.TestCase):
     def test_fields(self):
         self.assertEqual(fields(PlainData0), ())
@@ -182,6 +191,11 @@ class TestPlainData(unittest.TestCase):
                          "PlainData2(a=1, b=2, x='x', y='y', z=3)")
         self.assertEqual(repr(PlainDataF2(1, 2, x="x", y="y", z=3)),
                          "PlainDataF2(a=1, b=2, x='x', y='y', z=3)")
+        self.assertEqual(repr(UnsetField()),
+                         "UnsetField(a=<not set>, b=<not set>)")
+        self.assertEqual(repr(UnsetField(a=2)), "UnsetField(a=2, b=<not set>)")
+        self.assertEqual(repr(UnsetField(b=3)), "UnsetField(a=<not set>, b=3)")
+        self.assertEqual(repr(UnsetField(a=5, b=3)), "UnsetField(a=5, b=3)")
 
     def test_frozen(self):
         not_frozen = PlainData0()