]> git.ipfire.org Git - thirdparty/dnspython.git/commitdiff
Make dns.serial.Serial hashable (#1277)
authorVincent Gao <gaobing1230@gmail.com>
Sat, 27 Jun 2026 17:35:49 +0000 (19:35 +0200)
committerGitHub <noreply@github.com>
Sat, 27 Jun 2026 17:35:49 +0000 (10:35 -0700)
dns/serial.py
tests/test_serial.py

index 3417299be2bbb3726780f1ebf74bb16974cae308..603f5bc752e60f3bb55165ccab4a078ac0a95f7f 100644 (file)
@@ -18,6 +18,12 @@ class Serial:
             return NotImplemented
         return self.value == other.value
 
+    def __hash__(self):
+        # hash(self.value) satisfies the contract that a == b implies
+        # hash(a) == hash(b): Serial(v, bits) compares equal to the int v
+        # (after modular reduction), so its hash must equal hash(v).
+        return hash(self.value)
+
     def __ne__(self, other):
         if isinstance(other, int):
             other = Serial(other, self.bits)
index 8e6c43968c313216cfc8acbd11a4cd1dc98a7294..64463483aeeb797ee1b42efce69919a61c962f67 100644 (file)
@@ -126,3 +126,23 @@ class SerialTestCase(unittest.TestCase):
     def test_not_equal(self):
         self.assertNotEqual(S8(0), S8(1))
         self.assertNotEqual(S8(0), S2(0))
+
+    def test_hashable(self):
+        # Serial must be hashable so it can be used in sets and as dict keys.
+        s = S8(42)
+        self.assertEqual(hash(s), hash(42))
+
+        # Equal values hash the same.
+        self.assertEqual(hash(S8(1)), hash(S8(1)))
+
+        # Can be stored in a set.
+        seen = {S8(0), S8(1), S8(2)}
+        self.assertIn(S8(1), seen)
+
+        # Can be used as a dict key.
+        d = {S8(100): "zone-a"}
+        self.assertEqual(d[S8(100)], "zone-a")
+
+        # hash(Serial(v)) == hash(v) (int), satisfying the equality contract.
+        self.assertEqual(hash(S8(0)), hash(0))
+        self.assertEqual(hash(S8(255)), hash(255))