Fixing Incompatible Dunder Method Error in Mypy

Photo by Stephanie Mulrooney on Unsplash

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.



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store