LibCST
LibCST copied to clipboard
`FlattenSentinel` can't be used as return type annotation
Consider the following code:
MATCHER = m.FunctionDef(name=m.Name("__init__"))
class MyVisitor(...):
...
@m.leave(MATCHER)
def mutate_init(
self,
original_node: cst.FunctionDef,
updated_node: cst.FunctionDef
) -> cst.FlattenSentinel[cst.FunctionDef]:
...
This raises the following exception: TypeError: issubclass() arg 1 must be a class
https://github.com/Instagram/LibCST/blob/43a27b1222993f29086748ef6a08a57801c536aa/libcst/matchers/_visitors.py#L155-L157
Here, ret is cst.FlattenSentinel[cst.FunctionDef] (an instance of GenericAlias), annotation is libcst._nodes.statement.BaseStatement.
~~Works as expected without parametrizing the class~~
Edit: Fails at runtime as well without parametrizing the class:
libcst.matchers._visitors.MatchDecoratorMismatch: Invalid function signature for ForwardRelationOverloadCodemod.mutate_ManyToManyField_FunctionDef: @leave decorated function cannot return the type FlattenSentinel.
Tbh this runtime check of the return annotation is a bit surprising: type hints are not supposed to alter the run time behavior (except when explicitly advertised as is, e.g. like pydantic). It might be worth adding a try..except on this check, and only reraise if the exception is an instance of MatchDecoratorMismatch.