[ty] Avoid emitting cascading diagnostics when parsing invalid type expressions#24326
[ty] Avoid emitting cascading diagnostics when parsing invalid type expressions#24326AlexWaygood merged 6 commits intomainfrom
Conversation
Typing conformance results improved 🎉The percentage of diagnostics emitted that were expected errors increased from 86.61% to 86.79%. The percentage of expected errors that received a diagnostic held steady at 81.56%. The number of fully passing files held steady at 70/132. SummaryHow are test cases classified?Each test case represents one expected error annotation or a group of annotations sharing a tag. Counts are per test case, not per diagnostic — multiple diagnostics on the same line count as one. Required annotations (
Test file breakdown2 files altered
False positives removed (2)2 diagnostics
True positives changed (14)14 diagnostics
|
Memory usage reportSummary
Significant changesClick to expand detailed breakdowntrio
sphinx
prefect
|
|
| Lint rule | Added | Removed | Changed |
|---|---|---|---|
invalid-type-form |
0 | 135 | 1 |
invalid-await |
0 | 40 | 0 |
not-subscriptable |
13 | 0 | 0 |
possibly-missing-submodule |
0 | 4 | 0 |
unsupported-operator |
3 | 0 | 0 |
invalid-return-type |
0 | 1 | 0 |
unbound-type-variable |
0 | 1 | 0 |
| Total | 16 | 181 | 1 |
Changes in flaky projects detected. Raw diff output excludes flaky projects; see the HTML report for details.
Raw diff (157 changes)
django-stubs (https://github.com/typeddjango/django-stubs)
- django-stubs/contrib/gis/gdal/geometries.pyi:120:55 error[invalid-type-form] `...` is not allowed in this context in a type expression
- django-stubs/contrib/gis/gdal/geometries.pyi:123:31 error[invalid-type-form] Invalid subscript of object of type `property` in type expression
- django-stubs/contrib/gis/gdal/geometries.pyi:123:44 error[invalid-type-form] `...` is not allowed in this context in a type expression
- django-stubs/contrib/gis/gdal/geometries.pyi:123:50 error[invalid-type-form] `...` is not allowed in this context in a type expression
+ django-stubs/contrib/gis/gdal/geometries.pyi:123:31 error[not-subscriptable] Cannot subscript object of type `property` with no `__getitem__` method
- django-stubs/contrib/gis/gdal/geometries.pyi:125:30 error[invalid-type-form] Invalid subscript of object of type `property` in type expression
- django-stubs/contrib/gis/gdal/geometries.pyi:125:43 error[invalid-type-form] `...` is not allowed in this context in a type expression
- django-stubs/contrib/gis/gdal/geometries.pyi:125:49 error[invalid-type-form] `...` is not allowed in this context in a type expression
+ django-stubs/contrib/gis/gdal/geometries.pyi:125:30 error[not-subscriptable] Cannot subscript object of type `property` with no `__getitem__` method
- django-stubs/contrib/gis/gdal/geometries.pyi:145:31 error[invalid-type-form] Invalid subscript of object of type `property` in type expression
- django-stubs/contrib/gis/gdal/geometries.pyi:145:37 error[invalid-type-form] Invalid subscript of object of type `property` in type expression
- django-stubs/contrib/gis/gdal/geometries.pyi:145:50 error[invalid-type-form] `...` is not allowed in this context in a type expression
- django-stubs/contrib/gis/gdal/geometries.pyi:145:56 error[invalid-type-form] `...` is not allowed in this context in a type expression
- django-stubs/contrib/gis/gdal/geometries.pyi:145:62 error[invalid-type-form] `...` is not allowed in this context in a type expression
+ django-stubs/contrib/gis/gdal/geometries.pyi:145:31 error[not-subscriptable] Cannot subscript object of type `property` with no `__getitem__` method
+ django-stubs/contrib/gis/gdal/geometries.pyi:145:37 error[not-subscriptable] Cannot subscript object of type `property` with no `__getitem__` method
- django-stubs/contrib/gis/gdal/geometries.pyi:147:30 error[invalid-type-form] Invalid subscript of object of type `property` in type expression
- django-stubs/contrib/gis/gdal/geometries.pyi:147:36 error[invalid-type-form] Invalid subscript of object of type `property` in type expression
- django-stubs/contrib/gis/gdal/geometries.pyi:147:49 error[invalid-type-form] `...` is not allowed in this context in a type expression
+ django-stubs/contrib/gis/gdal/geometries.pyi:147:30 error[not-subscriptable] Cannot subscript object of type `property` with no `__getitem__` method
+ django-stubs/contrib/gis/gdal/geometries.pyi:147:36 error[not-subscriptable] Cannot subscript object of type `property` with no `__getitem__` method
- django-stubs/contrib/gis/gdal/geometries.pyi:163:36 error[invalid-type-form] `...` is not allowed in this context in a type expression
- django-stubs/contrib/gis/gdal/geometries.pyi:165:35 error[invalid-type-form] `...` is not allowed in this context in a type expression
- django-stubs/contrib/gis/geos/collections.pyi:11:36 error[invalid-type-form] `...` is not allowed in this context in a type expression
- django-stubs/contrib/gis/geos/collections.pyi:13:35 error[invalid-type-form] `...` is not allowed in this context in a type expression
- django-stubs/contrib/gis/geos/coordseq.pyi:10:49 error[invalid-type-form] `...` is not allowed in this context in a type expression
- django-stubs/contrib/gis/geos/coordseq.pyi:32:35 error[invalid-type-form] `...` is not allowed in this context in a type expression
- django-stubs/contrib/gis/geos/linestring.pyi:9:49 error[invalid-type-form] `...` is not allowed in this context in a type expression
- django-stubs/contrib/gis/geos/linestring.pyi:12:31 error[invalid-type-form] Invalid subscript of object of type `property` in type expression
- django-stubs/contrib/gis/geos/linestring.pyi:12:44 error[invalid-type-form] `...` is not allowed in this context in a type expression
+ django-stubs/contrib/gis/geos/linestring.pyi:12:31 error[not-subscriptable] Cannot subscript object of type `property` with no `__getitem__` method
- django-stubs/contrib/gis/geos/linestring.pyi:14:30 error[invalid-type-form] Invalid subscript of object of type `property` in type expression
- django-stubs/contrib/gis/geos/linestring.pyi:14:43 error[invalid-type-form] `...` is not allowed in this context in a type expression
+ django-stubs/contrib/gis/geos/linestring.pyi:14:30 error[not-subscriptable] Cannot subscript object of type `property` with no `__getitem__` method
- django-stubs/contrib/gis/geos/polygon.pyi:18:31 error[invalid-type-form] Invalid subscript of object of type `property` in type expression
- django-stubs/contrib/gis/geos/polygon.pyi:18:37 error[invalid-type-form] Invalid subscript of object of type `property` in type expression
- django-stubs/contrib/gis/geos/polygon.pyi:18:50 error[invalid-type-form] `...` is not allowed in this context in a type expression
+ django-stubs/contrib/gis/geos/polygon.pyi:18:31 error[not-subscriptable] Cannot subscript object of type `property` with no `__getitem__` method
+ django-stubs/contrib/gis/geos/polygon.pyi:18:37 error[not-subscriptable] Cannot subscript object of type `property` with no `__getitem__` method
- django-stubs/contrib/gis/geos/polygon.pyi:20:30 error[invalid-type-form] Invalid subscript of object of type `property` in type expression
- django-stubs/contrib/gis/geos/polygon.pyi:20:36 error[invalid-type-form] Invalid subscript of object of type `property` in type expression
- django-stubs/contrib/gis/geos/polygon.pyi:20:49 error[invalid-type-form] `...` is not allowed in this context in a type expression
+ django-stubs/contrib/gis/geos/polygon.pyi:20:30 error[not-subscriptable] Cannot subscript object of type `property` with no `__getitem__` method
+ django-stubs/contrib/gis/geos/polygon.pyi:20:36 error[not-subscriptable] Cannot subscript object of type `property` with no `__getitem__` method
egglog-python (https://github.com/egraphs-good/egglog-python)
- python/egglog/builtins.py:542:95 error[invalid-type-form] Int literals are not allowed in this context in a type expression
- python/egglog/builtins.py:666:105 error[invalid-type-form] Int literals are not allowed in this context in a type expression
- python/egglog/builtins.py:1060:99 error[invalid-type-form] Int literals are not allowed in this context in a type expression
- python/egglog/thunk.py:41:37 error[unbound-type-variable] Type variable `T` is not bound to any outer generic context
- python/tests/test_convert.py:117:51 error[invalid-type-form] Int literals are not allowed in this context in a type expression
- python/tests/test_convert.py:140:49 error[invalid-type-form] Int literals are not allowed in this context in a type expression
mypy (https://github.com/python/mypy)
- mypy/typeshed/stdlib/typing.pyi:529:36 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:535:36 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:540:40 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:564:37 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:564:49 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:564:64 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:581:48 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:618:42 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:623:38 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:624:42 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:628:48 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:635:30 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:640:30 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:661:68 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:666:36 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:667:40 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:677:75 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:683:69 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:693:39 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:697:41 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:705:42 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:705:65 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:710:66 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:712:66 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:726:39 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:728:40 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:758:36 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:769:36 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:788:34 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:788:39 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:789:32 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:790:36 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:905:42 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:909:36 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:911:31 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:418:53 error[invalid-type-form] Bare ParamSpec `_P` is not valid in this context in a type expression
- mypy/typeshed/stdlib/typing.pyi:418:57 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:418:74 error[invalid-type-form] Bare ParamSpec `_P` is not valid in this context in a type expression
- mypy/typeshed/stdlib/typing.pyi:418:78 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:630:69 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:711:41 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:711:64 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:711:72 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
+ mypy/typeshed/stdlib/typing.pyi:711:64 error[unsupported-operator] Operator `|` is not supported between two objects of type `TypeVar`
- mypy/typeshed/stdlib/typing.pyi:713:42 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:713:65 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:713:73 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
+ mypy/typeshed/stdlib/typing.pyi:713:65 error[unsupported-operator] Operator `|` is not supported between two objects of type `TypeVar`
- mypy/typeshed/stdlib/typing.pyi:739:42 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:741:40 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:744:38 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:745:39 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:747:40 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:748:39 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:749:40 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:754:42 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:756:40 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:759:38 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:760:39 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:762:40 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:763:39 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:764:40 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:814:41 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypy/typeshed/stdlib/typing.pyi:814:46 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
+ mypy/typeshed/stdlib/typing.pyi:814:46 error[unsupported-operator] Operator `|` is not supported between objects of type `TypeVar` and `None`
- mypy/typeshed/stdlib/typing_extensions.pyi:647:25 error[invalid-type-form] Variable of type `Literal[Format.STRING]` is not allowed in a type expression
- mypy/typeshed/stdlib/typing_extensions.pyi:656:25 error[invalid-type-form] Variable of type `Literal[Format.FORWARDREF]` is not allowed in a type expression
- mypy/typeshed/stdlib/typing_extensions.pyi:675:25 error[invalid-type-form] Variable of type `Literal[Format.STRING]` is not allowed in a type expression
- mypy/typeshed/stdlib/typing_extensions.pyi:686:25 error[invalid-type-form] Variable of type `Literal[Format.FORWARDREF]` is not allowed in a type expression
- mypyc/test-data/fixtures/typing-full.pyi:64:37 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypyc/test-data/fixtures/typing-full.pyi:82:38 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypyc/test-data/fixtures/typing-full.pyi:82:41 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypyc/test-data/fixtures/typing-full.pyi:82:44 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypyc/test-data/fixtures/typing-full.pyi:86:38 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypyc/test-data/fixtures/typing-full.pyi:95:35 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypyc/test-data/fixtures/typing-full.pyi:98:44 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypyc/test-data/fixtures/typing-full.pyi:98:47 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypyc/test-data/fixtures/typing-full.pyi:103:38 error[invalid-type-form] Variable of type `object` is not allowed in a type expression
- mypyc/test-data/fixtures/typing-full.pyi:103:43 error[invalid-type-form] Variable of type `object` is not allowed in a type expression
- mypyc/test-data/fixtures/typing-full.pyi:103:48 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypyc/test-data/fixtures/typing-full.pyi:121:43 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypyc/test-data/fixtures/typing-full.pyi:125:43 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypyc/test-data/fixtures/typing-full.pyi:127:38 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypyc/test-data/fixtures/typing-full.pyi:134:32 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypyc/test-data/fixtures/typing-full.pyi:140:34 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypyc/test-data/fixtures/typing-full.pyi:89:44 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypyc/test-data/fixtures/typing-full.pyi:92:74 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypyc/test-data/fixtures/typing-full.pyi:137:37 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypyc/test-data/fixtures/typing-full.pyi:139:40 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypyc/test-data/fixtures/typing-full.pyi:139:46 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypyc/test-data/fixtures/typing-full.pyi:139:59 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypyc/test-data/fixtures/typing-full.pyi:139:65 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypyc/test-data/fixtures/typing-full.pyi:141:33 error[invalid-type-form] Invalid subscript of object of type `Literal[0]` in type expression
- mypyc/test-data/fixtures/typing-full.pyi:141:39 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
- mypyc/test-data/fixtures/typing-full.pyi:141:42 error[invalid-type-form] Variable of type `TypeVar` is not allowed in a type expression
+ mypyc/test-data/fixtures/typing-full.pyi:141:33 error[not-subscriptable] Cannot subscript object of type `Literal[0]` with no `__getitem__` method
pandas (https://github.com/pandas-dev/pandas)
- pandas/core/series.py:324:21 error[invalid-type-form] Variable of type `Accessor` is not allowed in a type expression
pydantic (https://github.com/pydantic/pydantic)
- pydantic/v1/annotated_types.py:13:50 error[invalid-type-form] The special form `typing.TypedDict` is not allowed in type expressions
- pydantic/v1/annotated_types.py:24:26 error[invalid-type-form] The special form `typing.TypedDict` is not allowed in type expressions
- pydantic/v1/validators.py:621:26 error[invalid-type-form] The special form `typing.TypedDict` is not allowed in type expressions
spack (https://github.com/spack/spack)
- lib/spack/spack/detection/path.py:228:45 warning[possibly-missing-submodule] Submodule `package_base` might not have been imported
- lib/spack/spack/detection/path.py:254:29 warning[possibly-missing-submodule] Submodule `package_base` might not have been imported
- lib/spack/spack/detection/path.py:360:45 warning[possibly-missing-submodule] Submodule `package_base` might not have been imported
- lib/spack/spack/detection/path.py:386:45 warning[possibly-missing-submodule] Submodule `package_base` might not have been imported
static-frame (https://github.com/static-frame/static-frame)
- static_frame/test/unit/test_type_clinic.py:459:21 error[invalid-type-form] List literals are not allowed in this context in a type expression: Did you mean `tuple[int, int]`?
+ static_frame/test/unit/test_type_clinic.py:459:21 error[invalid-type-form] List literals are not allowed in this context in a type expression
xarray (https://github.com/pydata/xarray)
- xarray/core/indexing.py:427:40 error[invalid-type-form] `...` is not allowed in this context in a type expression
- xarray/core/indexing.py:433:35 error[invalid-type-form] `...` is not allowed in this context in a type expression
carljm
left a comment
There was a problem hiding this comment.
Results look good. I would like to understand the subscript change better.
| if matches!( | ||
| &*subscript.value, | ||
| ast::Expr::Name(_) | ast::Expr::Attribute(_) | ||
| ) { | ||
| builder.infer_type_expression(expr) | ||
| } else { | ||
| builder.infer_expression(expr, TypeContext::default()) | ||
| } |
There was a problem hiding this comment.
This seems deserving of a comment to explain the rationale for why different expressions should be treated differently. This doesn't seem to match the logic described in the PR summary, in that we aren't deciding to stop using infer_type_expression here due to an outer invalid-type-expression error.
Unless the rationale here is that a subscript should always be a name/attribute, and anything else will be an error? But if that's it, then couldn't this cause us to miss emitting an error we should emit?
There's also a similar (non-?)issue here as in other places, where we'll now emit value-expression errors on the subscript expression that we wouldn't have before, e.g. unresolved-reference in def f(x: "list[int][foo()]") -> None: ....
There was a problem hiding this comment.
Unless the rationale here is that a subscript should always be a name/attribute, and anything else will be an error? But if that's it, then couldn't this cause us to miss emitting an error we should emit?
I think that's what we should be doing, yes (see #24329).
I'm inclined to rip this change out of this PR for now, though, and maybe include it as part of #24329 instead.
There was a problem hiding this comment.
I've ripped out all changes to builder/subscript.rs for now.
crates/ty_python_semantic/src/types/infer/builder/type_expression.rs
Outdated
Show resolved
Hide resolved
| .iter() | ||
| .map(|element| self.infer_type_expression(element)) | ||
| .collect(); | ||
| self.infer_list_expression(list, TypeContext::default()); |
There was a problem hiding this comment.
In some scenarios this adds new diagnostics that we don't emit on main, e.g.
def f(x: "[foo()]") -> None: ...This PR emits both the "list literal not allowed" message and "foo not defined" -- the latter is not emitted on main. But main does emit an additional "call not allowed", which this PR omits.
I think that's fine?
There was a problem hiding this comment.
I've changed it so that we skip the infer_expression() calls entirely if we're inside a stringized annotation. That means that we still get errors about unresolved references inside invalid-in-type-expression AST nodes (which I think is desirable), but we avoid false-positive diagnostics like that inside stringized annotations
| | SpecialFormType::AlwaysTruthy | ||
| | SpecialFormType::AlwaysFalsy => { | ||
| self.infer_type_expression(arguments_slice); | ||
| self.infer_expression(arguments_slice, TypeContext::default()); |
There was a problem hiding this comment.
Similar to above, now def f(x: "Any[foo()]") -> None: ... emits an unresolved-reference on foo that main doesn't emit. But I think that's OK.
| ) -> Type<'db> { | ||
| if matches!( | ||
| &*subscript.value, | ||
| ast::Expr::Name(_) | ast::Expr::Attribute(_) |
There was a problem hiding this comment.
What if the subscript is a string-quoted name/attribute expression?
There was a problem hiding this comment.
that's an invalid type expression -- you should quote the whole subscript expression, not just the value. "list"[int] is going to fail at runtime on Python <3.14, there's no reason to write that even on newer Python versions, and it's not permitted by the grammar at https://typing.python.org/en/latest/spec/annotations.html#type-and-annotation-expressions. Just write "list[int]" instead.
There was a problem hiding this comment.
I was actually confused about whether this was checking the "value" or the "slice" expression -- that makes sense.
ae1f280 to
06909e8
Compare
a18198c to
9ddda47
Compare
Summary
In lots of places in our type-expression parsing, we continue to call
self.infer_type_expression()on sub-expressions in the AST even after we've already determined that the type expression is invalid. I think that's generally a mistake; it often leads to us emitting many diagnostics on a single type expression when one would really be sufficient. This PR switches many callsites frominfer_type_expressiontoinfer_expression, to avoid this phenomenon of cascading diagnostics in error cases.Test Plan
Mdtests and snapshots updated.