Skip to content

Conversation

AlexWaygood
Copy link
Member

Summary

This PR reworks TypeInferenceBuilder::infer_type_expression() so that we emit diagnostics when encountering a list literal in a type expression. The only place where a list literal is allowed in a type expression is if it appears as the first argument to Callable[], and Callable is already heavily special-cased in our type-expression parsing.

In order to ensure that list literals are always allowed as the first argument to Callabler (but never allowed as the second, third, etc. argument), I had to do some refactoring of our type-expression parsing for Callable annotations.

Test Plan

New mdtests added, and existing ones updated

@AlexWaygood AlexWaygood added the ty Multi-file analysis & type inference label Mar 19, 2025
Comment on lines 64 to 67
# error: [invalid-type-form] "Special form `typing.Callable` expected exactly two arguments (parameter types and return type)"
def _(c: Callable[[int, str]]):
reveal_type(c) # revealed: (int, str, /) -> Unknown
reveal_type(c) # revealed: (...) -> Unknown
```
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(int, str, /) -> Unknown is defensible here, but ultimately Callable[[int, str]] is invalid as an annotation, and I would prefer us to have a consistent fallback inference for all invalid Callable annotations.

@AlexWaygood
Copy link
Member Author

Cc. @dhruvmanila, since this touches on your work towards supporting Callable!

Copy link
Contributor

mypy_primer results

No ecosystem changes detected ✅

Copy link
Contributor

@carljm carljm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks fine to me. I don't think I agree about the importance of having an identical "dumb" fallback for every invalid Callable annotation, but I also don't think it matters much in any direction.

@AlexWaygood AlexWaygood merged commit a3f3d73 into main Mar 19, 2025
23 checks passed
@AlexWaygood AlexWaygood deleted the alex/invalid-list-type-exprs branch March 19, 2025 14:42
dcreager added a commit that referenced this pull request Mar 21, 2025
* main: (26 commits)
  Use the common `OperatorPrecedence` for the parser (#16747)
  [red-knot] Check subtype relation between callable types (#16804)
  [red-knot] Check whether two callable types are equivalent (#16698)
  [red-knot] Ban most `Type::Instance` types in type expressions (#16872)
  Special-case value-expression inference of special form subscriptions (#16877)
  [syntax-errors] Fix star annotation before Python 3.11 (#16878)
  Recognize `SyntaxError:` as an error code for ecosystem checks (#16879)
  [red-knot] add test cases result in false positive errors (#16856)
  Bump 0.11.1 (#16871)
  Allow discovery of venv in VIRTUAL_ENV env variable (#16853)
  Split git pathspecs in change determination onto separate lines (#16869)
  Use the correct base commit for change determination (#16857)
  Separate `BitXorOr` into `BitXor` and `BitOr` precedence (#16844)
  Server: Allow `FixAll` action in presence of version-specific syntax errors (#16848)
  [`refurb`] Fix starred expressions fix (`FURB161`) (#16550)
  [`flake8-executable`] Add pytest and uv run to help message for `shebang-missing-python` (`EXE003`) (#16855)
  Show more precise messages in invalid type expressions (#16850)
  [`flake8-executables`] Allow `uv run` in shebang line for `shebang-missing-python` (`EXE003`) (#16849)
  Add `--exit-non-zero-on-format` (#16009)
  [red-knot] Ban list literals in most contexts in type expressions (#16847)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ty Multi-file analysis & type inference
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants