Skip to content

Commit

Permalink
feat(api): make deferred objects hashable by their identity
Browse files Browse the repository at this point in the history
  • Loading branch information
jcrist committed Feb 27, 2024
1 parent 095e763 commit aa7aae5
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 9 deletions.
3 changes: 3 additions & 0 deletions ibis/common/deferred.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ def __bool__(self):
f"The truth value of {self.__class__.__name__} objects is not defined"
)

def __hash__(self):
return id(self)

def __getitem__(self, name):
return Deferred(Item(self, name))

Expand Down
24 changes: 15 additions & 9 deletions ibis/common/tests/test_deferred.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,10 +202,21 @@ def test_deferred_supports_string_arguments():
assert b.resolve({}) == "3.14"


def test_deferred_object_are_not_hashable():
# since __eq__ is overloaded, Deferred objects are not hashable
with pytest.raises(TypeError, match="unhashable type"):
hash(_.a)
def test_deferred_objects_are_hashable():
a = _.a
assert hash(a) == hash(a)

# Works in dicts
d = {a: 1, _.b: 2}
assert d[a] == 1
assert _.c not in d
assert _.a not in d # hash by identity only

# Works in sets
s = {a, a, _.b}
assert len(s) == 2
assert a in s
assert _.a not in s # hash by identity only


def test_deferred_const():
Expand Down Expand Up @@ -541,11 +552,6 @@ def myfunc(x):
assert repr(myfunc(_.a)) == "<test>"


def test_deferred_set_raises():
with pytest.raises(TypeError, match="unhashable type"):
{_.a, _.b} # noqa: B018


@pytest.mark.parametrize(
"case",
[
Expand Down

0 comments on commit aa7aae5

Please sign in to comment.