[ty] Improve invalid-type-form diagnostic where a module-literal type is used in a type expression and the module has a member which would be valid in a type expression (#18244)

This commit is contained in:
Alex Waygood 2025-05-21 15:38:56 -04:00 committed by GitHub
parent 41463396cf
commit 02394b8049
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 136 additions and 7 deletions

View file

@ -113,3 +113,35 @@ def _(
reveal_type(f) # revealed: Unknown
reveal_type(g) # revealed: Unknown
```
## Diagnostics for common errors
<!-- snapshot-diagnostics -->
### Module-literal used when you meant to use a class from that module
It's pretty common in Python to accidentally use a module-literal type in a type expression when you
*meant* to use a class by the same name that comes from that module. We emit a nice subdiagnostic
for this case:
`foo.py`:
```py
import datetime
def f(x: datetime): ... # error: [invalid-type-form]
```
`PIL/Image.py`:
```py
class Image: ...
```
`bar.py`:
```py
from PIL import Image
def g(x: Image): ... # error: [invalid-type-form]
```

View file

@ -0,0 +1,62 @@
---
source: crates/ty_test/src/lib.rs
expression: snapshot
---
---
mdtest name: invalid.md - Tests for invalid types in type expressions - Diagnostics for common errors - Module-literal used when you meant to use a class from that module
mdtest path: crates/ty_python_semantic/resources/mdtest/annotations/invalid.md
---
# Python source files
## foo.py
```
1 | import datetime
2 |
3 | def f(x: datetime): ... # error: [invalid-type-form]
```
## PIL/Image.py
```
1 | class Image: ...
```
## bar.py
```
1 | from PIL import Image
2 |
3 | def g(x: Image): ... # error: [invalid-type-form]
```
# Diagnostics
```
error[invalid-type-form]: Variable of type `<module 'datetime'>` is not allowed in a type expression
--> src/foo.py:3:10
|
1 | import datetime
2 |
3 | def f(x: datetime): ... # error: [invalid-type-form]
| ^^^^^^^^
|
info: Did you mean to use the module's member `datetime.datetime` instead?
info: rule `invalid-type-form` is enabled by default
```
```
error[invalid-type-form]: Variable of type `<module 'PIL.Image'>` is not allowed in a type expression
--> src/bar.py:3:10
|
1 | from PIL import Image
2 |
3 | def g(x: Image): ... # error: [invalid-type-form]
| ^^^^^
|
info: Did you mean to use the module's member `Image.Image` instead?
info: rule `invalid-type-form` is enabled by default
```