Search code examples
pythonpython-typingmypy

How to check if variable is of type TypeVar(bound=X)


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?


Solution

  • 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)