Instagram / Instagram/LibCST

`FlattenSentinel` can't be used as return type annotation

Open
#1,075 1 comment 1 reaction 0 assignees View on GitHub
bug machinery
Dominant language
Python
Stars
1.9k
Forks
229
PR merge metrics
No merged PRs in 30d

Description

Consider the following code:

```python
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`.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.