Fixing “None” Not Callable Error in Mypy
A neat trick to have dict.get() return something that isn’t callable.
The mypy static type checker always complain about using a dictionary to call functions. Especially this code segment from a chess program that I’m writing in Python as a learning exercise.
status = {Bishop: self.validate_move_bishop,
King: self.validate_move_king,
Knight: self.validate_move_knight,
Pawn: self.validate_move_pawn,
Queen: self.validate_move_queen,
Rook: self.validate_move_rook,
}.get(type(self._board[start]))(start, end)
This message, error: “None” not callable
, always leave me cross-eyed at times.
The self._board
is a dictionary with 64 key-value pairs that represent the squares of the chess board. The key is a (file, rank)
tuple for the position, and the value is either a Piece subclass or None for an empty square.
When self._board
with the start
position is passed to the dictionary, the type of the Piece subclass is used as a key to call the corresponding function and return a Boolean to status
.
I know my testing code wasn’t passing None
to the status
dictionary. So where was None
coming from for mypy to complain about it?
The dict.get()
function returns None
as the default value when no valid key exist. An alternative default value can be assigned. Since the corresponding functions returned a Boolean for assignment to status
, I assigned False
as the default value.
status = {...}.get(type(self._board[start]), False)(start, end)
This message, error: "bool" not callable
, left me even more cross-eyed. How do I return a non-callable Boolean to status
as the default value?
A not so quick Google search revealed a neat trick for solving this problem.
status = {...}.get(type(self._board[start]),
lambda *args: False)(start, end)
Assign lambda
as an anonymous function that does nothing with the function arguments, (start, end)
, and return False
for the default value. The code still works, mypy is happy, and I’m less cross-eyed from not seeing that error message.
Please follow me on Medium. Your support is greatly appreciated.