From: Vincent Gao Date: Sat, 27 Jun 2026 17:35:49 +0000 (+0200) Subject: Make dns.serial.Serial hashable (#1277) X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f1b0314ffe0e128d753b1279629111729849f515;p=thirdparty%2Fdnspython.git Make dns.serial.Serial hashable (#1277) --- diff --git a/dns/serial.py b/dns/serial.py index 3417299b..603f5bc7 100644 --- a/dns/serial.py +++ b/dns/serial.py @@ -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) diff --git a/tests/test_serial.py b/tests/test_serial.py index 8e6c4396..64463483 100644 --- a/tests/test_serial.py +++ b/tests/test_serial.py @@ -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))