mentalisttraceur / python-macaddress

BSD Zero Clause License
19 stars 5 forks source link

Explicitly overloading `__ne__` #10

Closed mentalisttraceur closed 2 years ago

mentalisttraceur commented 2 years ago

We should probably delete HWAddress.__ne__, and let Python automatically implicitly implement it.

Thoughts?

mentalisttraceur commented 2 years ago

To be totally honest, when I first implemented this, I didn't remember, and perhaps just didn't know, that as of Python 3, __ne__ had a default implementation that negated __eq__. One of the side effects of investing so hard into portable habits and constructs is that you start to miss ways you can take advantage of the new stuff.

But once I was reminded/educated of this, I only briefly removed __ne__, before undoing it and putting back in the manual overload. Because deep down I still have bad compulsions towards manually optimizing performance and portability.

In Python 2 __ne__ had to be explicitly overloaded, because it is not automatically implemented as a negation of __eq__. This library only supports Python 3 (forcing myself to not support Python 2 in this library was possibly the nicest gift and mercy that I have ever given myself).

I am also trying my best to resist my urge to bend my code for possibly incomplete or imperfect Python 3 implementations. (I'm sure Brython, MicroPython, Transcrypt, Skulpt, etc, all implement unoverloaded __ne__ as negation of __eq__, and if they don't, the right place to fix that is not in every single implementation of a class that overloads __eq__.)

But I still felt a little compelled by that portability conservatism, by compassion for a hypothetical user in a contrived circumstance on a contrived Python 3 implementation where it doesn't work like that and isn't easy enough to fix by monkey-patching.

I also felt that tiny compulsion to make the execution straightforward. I made the classic mistake of letting insight into the existing implementations effect my reasoning more than vision of better automatic optimization. I knew better. I've even preached against it repeatedly. I've had this realization over and over and over that I should trust the vision of the sufficiently advanced hypothetical optimizer. And still I let this sway me.

My head filled with images of users seeing stack traces possibly with extra calls (so?!), of the interpreter having to do a whole additional method lookup (on a class hierarchy only three deep or so! I've probably already spent more of my life thinking about it than computers will ever waste on looking up that __eq__ after failing to find __ne__), and of other tiny overheads for which automatic optimizations have existed for decades.

Also as a very tiny nuance, I had mixed feelings about how the help/docstring for the __ne__ method looked if I didn't overload it.

Sigh.

So it tipped the scales in my mind. "Oh, I'll just implement the __ne__ manually, what's the harm?"

mentalisttraceur commented 2 years ago

Well it just hit me that if a user wants to subclass a HWAddress class and change equality, then HWAddress implementing __ne__ forces them to also implement __ne__!

And that's bad. If we were still living the Python 2 life, where everyone should overload both anyway, that would be fine, but in Python 3 developers can generally expect, and fully deserve to always get, the behavior where they only need to overload __eq__.

mentalisttraceur commented 2 years ago

Fixed in 91378bd4457ed767e04876a0d16e7fd9cdde13c3.