From ad3f7e7b5d81b1384189f7be821ce5530cd2f16d Mon Sep 17 00:00:00 2001 From: dualfroz Date: Fri, 4 Sep 2026 09:39:40 +0200 Subject: [PATCH] fix: make Delorean hashable by defining __hash__ Defining __eq__ without __hash__ sets __hash__ to None in Python 3, so Delorean instances were unhashable and could not be used in sets or as dict keys (unlike datetime). Hash on self.epoch, the same value __eq__ compares, so equal instances hash equal. --- delorean/dates.py | 4 ++++ tests/delorean_tests.py | 14 ++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/delorean/dates.py b/delorean/dates.py index 4dc00ba..fac318d 100644 --- a/delorean/dates.py +++ b/delorean/dates.py @@ -240,6 +240,10 @@ class Delorean(object): return self.epoch == other.epoch return False + def __hash__(self): + # Hash on what __eq__ compares, so equal instants hash equal. + return hash(self.epoch) + def __lt__(self, other): return self.epoch < other.epoch diff --git a/tests/delorean_tests.py b/tests/delorean_tests.py index 5ab5061..5bdfa6f 100644 --- a/tests/delorean_tests.py +++ b/tests/delorean_tests.py @@ -50,6 +50,20 @@ class DeloreanTests(unittest.TestCase): dt = date(2013, 5, 6) self.assertRaises(ValueError, delorean.Delorean, dt) + def test_hashable(self): + # Defining __eq__ without __hash__ makes instances unhashable in Python 3. + self.assertEqual(hash(self.do), hash(self.do)) + self.assertIn(self.do, {self.do}) + mapping = {self.do: "value"} + self.assertEqual(mapping[self.do], "value") + + def test_hash_consistent_with_equality(self): + # Equal objects (same instant, different timezone) must hash equal. + other = self.do.shift("US/Pacific") + self.assertEqual(self.do, other) + self.assertEqual(hash(self.do), hash(other)) + self.assertEqual(len({self.do, other}), 1) + def test_initialize_from_datetime_naive(self): self.assertRaises( delorean.DeloreanInvalidTimezone, delorean.Delorean, datetime=self.naive_dt