issubclass
vs. is
for narrowing types
#1874
-
The below is a much reduced form of an existing conversion function I'm adding typing to. Its job is to convert a provided "raw" value (received from an API, fwiw) to an expected type if possible else provide a dummy value of the expected type if it can't do the conversion. from typing import Any, TypeVar
_T = TypeVar('_T', str, int, list[Any], covariant=False)
def convert_value(value: Any, data_type: type[_T]) -> _T:
if data_type is list:
if isinstance(value, (list, set, tuple)):
return data_type(value)
else:
return [value]
elif data_type is int:
if value.isdecimal():
return data_type(value)
return data_type()
else: # data_type is str
return data_type(value) A sample user of which might look like: >>> convert_value('abc', list)
['abc']
>>> convert_value('123', str)
123
>>> convert_value('abc', str)
0 This doesn't behave as I expect and yields the following error:
If I replace the |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
So That being said, the the fact that mypy makes it a no-op both in the positive and negative case can be a little frustrating, since the positive case could be narrowed safely, but at the same time it's probably a good idea to discourage the use of type identity for type narrowing, since it's not reliable. |
Beta Was this translation helpful? Give feedback.
data_type
could always be a subclass oflist
orint
as well, using a constrained type var does not prevent that. Variance doesn't really have any meaning in generic functions, it just has to find aT
that produces a signature that could accept your input type. So if you substituteint
any subclass ofint
can be passed into the function, just like if you had annotated the function withint
.So
is
is not sufficient for narrowing classes that haven't been decorated with@final
to prevent subclasses. Type checkers could narrow toint & ~Exactly[int]
in the negative case but in practice that's not really useful, unless you're working with ADTs where you have a finite statically known number of…