So I'm implementing a search algorithm for a 8-puzzle, and like any good search algo it runs on parallel. I'm storing results of each run inside a queue, at the end I'm checking the only value stored inside queue witch is ether int for some error, Game for actual answer and None for 'answer doesn't exists'.
Here is my code:
from typing import TypeVar
from multiprocessing import Queue
class Game:
...
G = TypeVar('G', bound=Game)
def search(initial_state: G) -> G:
results: Queue[int | G | None] = Queue()
...
game = results.get()
assert game is Game # here is the problem
return game
Values of queue are ether int, None or a subclass of Game
class.
The queue is also responsible for return type of search
function so I should check if game is exactly of type G or raise error otherwise.
I'm using Mypy for type checking, all my attempt fail to check if results.get()
is G
Meanwhile I tried:
assert game is Game
# ---
assert isinstance(game, Game)
# ---
assert issubclass(game, Game)
# ---
assert isinstance(game, Game) or issubclass(game, Game)
But Mypy complains neither is exactly of type G
What should I do to check if results.get()
is returning the same type as input?
You have to do it the other way round and exclude the other possibilities
def search(gamein: G) -> G:
results: Queue[int | G | None] = Queue()
game = results.get()
reveal_type(game) # int | G | None
assert not isinstance(game, int)
assert game is not None
reveal_type(game) # G
return game
Note: pyright has a slight nuance here, it will treat the final game
as a conditional Game*
and will not report an error even if you use isinstance(game, Game)