A Magic Implementation of NotImplemented
- Level:
- intermediate
- Room:
- terrace 2b
- Start:
- Duration:
- 30 minutes
Abstract
Dirty Equals is a new python library by Samuel Colvin, the creator of Pydantic. It will transform how you write tests, especially for APIs.
I made some contributions to it, which forever changed how I thought about NotImplemented
. I thought it was a placeholder for unfinished work and unexpected use cases. I thought the language quirks it created in equality comparison were annoying.
But in DirtyEquals, it’s a magic way to transform Python’s built in equality operator... And that changed how I think about language quirks, full stop.
Description
Intro (5m)
I adore Pydantic. It's a fantastic library that creates classes which check types at Python runtime. In short, it turns type hints into static types.
I had a crush on the code that did this. I thought it was so cool to trick Python into behaving this way. I wanted to learn how this library worked. But when I went to contribute to it, I saw it wasn't looking for contributions.
So, I decided to look at his other projects in the hope I could learn something there.
What is Dirty Equals (10m)
This is how I discovered DirtyEquals. This library lets you write tests in a whole new way. With DirtyEquals., you get to (mis)use Python’s equality operator in way that speeds up testing.
DirtyEquals lets you write assert statements that compare objects to custom types, This makes your tests more declarative and more readable. I’ll go over several examples in this section.
How Does It Work (10m)
You might be thinking, isn’t it strange that the Python equality operator can work in this way? Shouldn’t it return False, since the DirtyEquals. types are different to the types they’re compared to?
This is where things get interesting. It turns out that if you write x == y
in Python, three things happen:
- First, Python looks at
x.__eq__
to see if x and y are the same. - If
y
is a new type, it returnsNotImplemented
because they
's type isn’t part of Python’s built ins. So there isn’t an implementation for how Python checks the type for equality. - But - here’s the kooky bit - Python then checks
y.__eq__
! So if we can hook into they.__eq__
part, we can write our own rules for the equality operator.
There are so many things you can do mucking around with .__eq__
and .__ne__
, which is what I’ll cover in this section.
Conclusion (5m)
When it comes to coding, I think we should pursue our crushes. If there’s code that you find attractive, then see if you can contribute! As a result, I learnt things I would never have learnt any other way.
In fact, the main thing I learnt was a completely different approach to coding. To me, mucking around with the .__eq__
seemed like a terrible idea that would cause untold errors.
But when I saw someone else do it so well, it seemed like a magic trick. I now no longer think of language quirks as problems. I consider them opportunities to perform magic tricks.