Closed Daverball closed 10 months ago
This sounds good, but what exactly causes it to fail at runtime?
Neither str
nor NoneType
implement __or__
or __ror__
, also both type.__ror__
and type.__or__
reject str
as an operand. The reason being probably, that they didn't want to add __or__
/__ror__
to NoneType
or str
, which would be necessary to allow all the possible permutations, so it's better to just always reject str
.
The main reason why type checkers don't catch this currently, is probably because __or__
/__ror__
need to support special form types, such as Optional
and there's no way to spell this in the type system, so currently the operand's annotation is Any
, even though it technically should reject anything that isn't a valid type.
A fairly common mistake when partially wrapping/unwrapping annotations are expressions like:
These are always invalid at runtime and generate a
TypeError
(they're fine at type checking time, since it is treated the same asUnion['SomeType', None]
)I think it would be fairly easy to catch this mistake and add a new rule for it. Essentially any time we encounter a
ast.BinOp
/ast.BitOr
inside a type annotation and either one of the operands is anast.Constant
, it should generate an error.