question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

__eq__ and __ne__ are implemented incorrectly for all classes

See original GitHub issue

__eq__ and __ne__ are implemented incorrectly throughout the entire google-cloud-* code base. I encountered this issue when trying to compare a google.cloud.datastore.Key instance to unittest.mock.ANY.

When implementing custom equality in Python (2 or 3), it should be written like this:

class A:
    def __eq__(self, other):
        if not isinstance(other, A):
            # Delegate comparison to the other instance's __eq__.
            return NotImplemented
        # Whatever logic applies to equality of instances of A can be added here.
        ...

    def __ne__(self, other):
        # By using the == operator, the returned NotImplemented is handled correctly.
        return not self == other

Throughout the entire code base of this repository, equality is implemented like this:

class A:
    def __eq__(self, other):
        if not isinstance(other, A):
            # Other instances are never equal.
            return False
        # Whatever logic applies to equality of instances of A can be added here.
        ...

    def __ne__(self, other):
        # By negating the return value, NotImplemented is treated as False.
        return not self.__eq__(other)

As a result gcloud instances can never equal entities of other classes if they are the first object in the comparison. This is not an issue for most cases, but there are cases where this is an issue. Also this behaviour is simply incorrect.

The __ne__ implementation works, because __eq__ is implemented incorrectly. The boolean value of NotImplemented is True.

>>> not NotImplemented
False

This is typically an issue when unittesting.

>>> from unittest.mock import ANY
>>> 
>>> from google.cloud.datastore import Client
>>> 
>>> 
>>> client = Client()
>>> key = client.key('foo')
>>> key == ANY  # Expected True
False
>>> ANY == key
True
>>> key != ANY  # Expected False
True
>>> ANY != key
False
>>> 

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:7 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
lukesneeringercommented, Aug 8, 2017

@remcohaszing Sanity check: Should the if isinstance(other, A): actually be if not isinstance(other, A):?

0reactions
lukesneeringercommented, Aug 8, 2017

Okay, that was what I thought, but I wanted to be polite.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Should __ne__ be implemented as the negation of __eq__?
Python, should I implement __ne__() operator based on __eq__ ? Short Answer: Don't implement it, but if you must, use == , not...
Read more >
Solved Introduction In this lab problem, we continue our - Chegg
In it you will see that several special functions have already been overloaded. It is your job to complete the class, implementing the...
Read more >
Python Hashes and Equality - Hynek Schlawack
Most Python programmers don't spend a lot of time thinking about how equality and hashing works. It usually just works.
Read more >
3. Data model — Python 3.11.1 documentation
A class can implement certain operations that are invoked by special syntax (such as arithmetic operations or subscripting and slicing) by defining methods...
Read more >
Where Companies Go Wrong with Learning and Development
Mandate that busy employees attend a training session on “business writing skills”, or “conflict resolution”, or some other such course with ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found