Fixing Incompatible Dunder Method Error in Mypy
When fixing one problem creates another problem in Python.
While cleaning up my code for a chess program that I’m writing in Python as a learning exercise, I created an Enum
class to represent the starting ranks for certain pieces on the board.
class Rank(Enum):
HIGH = [1, 8]
PAWN = [2, 7]
Ranks 1 and 8 are where the Bishops, King, Knights, Queen and Rooks start on the board. Ranks 2 and 7 are where the pawns start on the board. The corresponding ranks are stored in a two-item list
.
That didn’t work as intended with this code segment for the Pawn piece.
if self._first_move and (rank_start in Rank.PAWN):
...
The pytest
test runner reported an error.
Type Error: argument of type “Rank” is not iterable
The interpreter saw the type and not the value assigned to the Enum. That was an easy fix by adding .value
to Rank.PAWN.
if self._first_move and (rank_start in Rank.PAWN.value):
...
That fixes the code. But adding .value
made it appear less neat and tidy. The whole purpose of using an Enum
is to keep everything neat and tidy.
A quick Internet search revealed that I could add list
in addition to Enum
in the Rank
class definition. (Note that Enum
must be the last object for the class to work properly.)
class Rank(list, Enum):
HIGH = [1, 8]
PAWN = [2, 7]
Adding list
to the class definition turned Rank.PAWN
into an iterable without using .value
. A neat trick. That fixed one problem but created another problem.
The mypy
static type checker reported an error.
Definition of “__hash__” in base class “list” is incompatible with definition in base class “Enum”
That would be a serious concern if I was using the __hash__
dunder method in my code. Since I’m not, I can ignore this error.
A quick search of the mypy
documentation revealed that I could silence the error message by adding # type: ignore
to the class line.
class Rank(list, Enum): # type: ignore
HIGH = [1, 8]
PAWN = [2, 7]
That was a fun little rabbit hole for a Sunday morning.
This fix introduces a side effect that impacted the Sphinx documentation generator. That forced me to come up with a fix — replace list
with tuple
in the class definition and the square brackets with parentheses — that eliminated the side effect. Please follow me on Medium. Your support is greatly appreciated.