will f
will f

Reputation: 483

Implement __eq__ for a module

I see that a module can be compared to other objects with the standard == and != operators.

Is it possible to override the “rich comparison” methods __eq__ and __ne__ of a module to customize their comparison? I am specifically looking to have the module resolve itself to a tuple defined within itself during the comparison in these methods.

I tried, eg for module m, adding the line __eq__ = lambda other: other == m.my_tuple in the desired module, but it does not work.

Upvotes: 0

Views: 157

Answers (1)

ShadowRanger
ShadowRanger

Reputation: 155546

Modules are instances of the module class/type. __eq__ (and most special methods) must be implemented on the type itself to be used (you can't assign to __eq__ on an instance and have it acquire new comparison rules). Your module being an instance means it can't overload special methods (aside from some special cases specifically allowed for, like __getattr__); even if defined, __eq__ will be ignored.

You could theoretically overload __eq__ on some other user-defined type such that it would allow comparisons to module (even if the module is on the left hand side of the comparison, the module __eq__ would return NotImplemented and then your other type would have it's own __eq__ invoked to see if it knows how to compare to modules), but it's a terrible idea.

In short, this makes no sense. A module is equal to itself and nothing else; the idea that two independent modules should be treated as equivalent is bonkers on its face. I strongly suspect you have an XY problem and need to find a better way of solving your real problem rather than trying to make something terrible like this work.


Having said all that, it is technically possible to make module subclasses and replace the class of a module with that subclass. An example is provided in the docs to use this to customize the stringified form of the module. That same technique could be used to retroactively overload the meaning of __eq__ after the module has been imported. Please never do this:

import sys
from types import ModuleType

class WeirdCompareModule(ModuleType):
    def __eq__(self, other):
        if isinstance(other, tuple):
            return self.my_tuple == other
        return NotImplemented

sys.modules[__name__].__class__ = WeirdCompareModule

my_tuple = 1, 2, 3

print(sys.modules[__name__] == (1, 2, 3))  # Prints True

Again, DO NOT DO THIS, this is to illustrate something you can do, not something you should do.

Upvotes: 7

Related Questions