diff --git a/satella/coding/structures/hashable_objects.py b/satella/coding/structures/hashable_objects.py index ede856418330feb41b5bbe4da004f34181d3b29f..33a8fb51e4d2c5eb1bbcbce7fc52e016e2c623c0 100644 --- a/satella/coding/structures/hashable_objects.py +++ b/satella/coding/structures/hashable_objects.py @@ -1,6 +1,11 @@ -def HashableWrapper(obj): +from .proxy import Proxy + + +class HashableWrapper(Proxy): """ - A decorator that makes given objects hashable by their id. + A class that makes given objects hashable by their id. + + Note that this class will return a proxy to the object, and not the object itself. Use like: @@ -12,6 +17,6 @@ def HashableWrapper(obj): >>> a.a = 4 >>> assert a.a == 4 """ - if not hasattr(obj, '__hash__'): - obj.__hash__ = lambda self: hash(id(self)) - return obj + + def __hash__(self): + return hash(id(self)) diff --git a/satella/coding/structures/proxy.py b/satella/coding/structures/proxy.py index 1e11ce0420af7ca3c3a2eb9aa0af0f4c668a7ef2..3d5109d233409e7fa3df31f2593da5ff7acc65b0 100644 --- a/satella/coding/structures/proxy.py +++ b/satella/coding/structures/proxy.py @@ -42,7 +42,7 @@ class Proxy(tp.Generic[T]): return getattr(self.__obj, item) def __delattr__(self, item): - del self.__obj[item] + delattr(self.__obj, item) def __int__(self): return int(self.__obj) diff --git a/tests/test_coding/test_structures.py b/tests/test_coding/test_structures.py index 56a2c1b8a79894c5b7eb51e9528b61f538eddebb..cb83fb6b9061aef50a070f508d9fac28aa684779 100644 --- a/tests/test_coding/test_structures.py +++ b/tests/test_coding/test_structures.py @@ -99,6 +99,9 @@ class TestMisc(unittest.TestCase): def __call__(self, *args, **kwargs): return 5 + def __hash__(self): + raise TypeError() + nh = NotHashable(5) nw = HashableWrapper(nh) self.assertEqual(nw.a, 5)