-
-
Notifications
You must be signed in to change notification settings - Fork 30.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Equivalent comparison operation in membership test operations for set container type is not 100% accurate. #116557
Comments
@ThePhar indeed! Would you like to send a PR? I think it would be something like:
|
wait a second :) |
print(a == 'True')
print(hash(a) == hash('True')) prints:
Your class is broken. From the
|
I've checked your example once again and found that you have both
and this is not the case for your class Foo:
def __init__(self, value: bool):
self.value = value
def __eq__(self, other):
return self.value == bool(other)
f = Foo(1)
print(any(f is e or f == e for e in {1, 2})) # True
print(any(f is e or f == e for e in {'a', 'b'})) # True
print(any(f is e or f == e for e in {''})) # False For a regular class without |
It is documented that a == b should imply that hash(a) == hash(b). Python works hard to make this so for builtins.
When so, hash(a) != hash(b) implies a != b. The doc intentionally says 'equivalent', not 'exactly equal'. The speed shortcut is an CPython implementation detail. not a language requirement. Closing. Please ask questions about CPython detail on, for instance, https://discuss.python.org/c/users/7, where many more people are likely to see answers. |
Documentation
The documentation for how the
in
andnot in
operator tests work describes the following:https://docs.python.org/3/reference/expressions.html#membership-test-operations
However, for sets this is not 100% the case as it will first attempt to hash the value to see if it exists in the set, and if not, skips over any
__eq__
comparisons so the equivalent expression:any(x is e or x == e for e in y)
never happens.Putting aside me jumping down a rabbit hole trying to find out why this doesn't work, it would be nice if the docs could be updated to clarify this additional check that is done for "hashable containers" like sets.
Simplified example:
The text was updated successfully, but these errors were encountered: