I'm using Python PEP484 type hints to write a type-checker for a DSL I've written in Python. If I have a function expecting type T
for one of its arguments, and it's being called with an expression of type S
, how can I check whether the call is valid? Is using issubclass(S, T)
enough? If so, why does mypy
have such a complicated is_subtype
check? Or should I just use the mypy
version?
Edit: Here's an example to clarify what I mean. The DSL has a function defined as:
T = TypeVar('T', float, str)
def op_add(operand1: T, operand2: T) -> T:
"Number addition or string concatenation."
# In this DSL, `+` cannot be used with lists
return operand1 + operand2 # Rely on Python overloading of `+`
Then a user types in an expression which is parsed into a syntax tree, with a branch that could be: node = OperatorNode('+', Literal([5.0]), Variable("abc"))
. We don't know the value of the abc
variable yet, but lists can never be used with +
, so I want to raise a TypeError
to alert the user.
If I do issubclass(typing.List[float], var)
, that gives me False, so I can raise an error right away. My question is whether this check is guaranteed to work across cases as I build out the DSL, or if I need to use a more complex check like mypy
issubclass
check is sufficient if neither argument to issubclass
includes constructs from typing
module such as Union
, Callable
, Any
, generics, etc.
typing
constructs exist in python runtime as a shadow of their true form, that is they don't support many of the operations that make sense conceptually:
issubclass(List[int], List[int]) # runtime error
issubclass(List[int], List) # True (as expected)
issubclass(str, Union[str]) # runtime error
issubclass(Union[str], str) # True (as expected)
issubclass(Union[int, str], str) # runtime error
Sometimes issubclass
will work with typing
constructs, but in general, it may raise an exception or give an incorrect answer; you'll need to figure out what to do on a case by case basis.
mypy
has a more complicated is_subtype
because it does need to handle all the typing
constructs, and even then there is still some work to be done there.