Repository navigation
Conversation
… annotations Python function calls are invalid type expressions in annotations (PEP 484), with native shape DSL calls as the exception in shape annotations. Previously, `allows_type_level_dsl_call()` returned true for all return annotations and any type arguments nested inside them. Consequently, any ordinary function call in a return annotation (e.g., `def f() -> make_type(): ...` or `Union[bool, make_type()]`) was passed to `parse_type_level_dsl_call`, producing a misleading error: `Expected a type-level DSL function, got ...`. This commit distinguishes shape DSL parameter contexts (`ShapeTypeArgument`) from ordinary generic type arguments, and checks whether the callee is an actual registered type-level DSL function before routing to the shape DSL parser. If not in a shape context and not a DSL function, it falls back to the standard "Function call cannot be used in annotations" error. This shouldn't change type-checking behavior—only more fine-grained control for better error messages. I think that is a clearer error message, as users may be confused by the "DSL" thing, but feel free to not accept this if you disagree. ```python from typing import Union def make_type() -> type[int]: ... def f() -> Union[bool, make_type()]: ... ``` - **Current behavior**: `Expected a type-level DSL function, got () -> type[int]` - **New behavior**: `Function call cannot be used in annotations` Added a test and run test.py
Contributor
|
This pull request has been imported. If you are a Meta employee, you can view this in D123101223. (Because this pull request was imported automatically, there will not be any future comments.) |
|
Diff from mypy_primer, showing the effect of this PR on open source code: ============================================================
SUMMARY
============================================================
Total: +3 new errors, -3 fixed errors
By preset: +3/-3 (default), +3/-3 (strict)
Projects with changes (1):
spark: +3 -3
============================================================
FULL DIFF DETAILS
------------------------------------------------------------
spark (https://github.com/apache/spark)
- ERROR python/pyspark/pandas/tests/test_typedef.py:217:36-39: Expected a type-level DSL function, got `type[zip]` [invalid-annotation]
+ ERROR python/pyspark/pandas/tests/test_typedef.py:217:36-64: Function call cannot be used in annotations [invalid-annotation]
- ERROR python/pyspark/pandas/tests/test_typedef.py:227:36-39: Expected a type-level DSL function, got `type[zip]` [invalid-annotation]
+ ERROR python/pyspark/pandas/tests/test_typedef.py:227:36-64: Function call cannot be used in annotations [invalid-annotation]
- ERROR python/pyspark/pandas/tests/test_typedef.py:239:36-39: Expected a type-level DSL function, got `type[zip]` [invalid-annotation]
+ ERROR python/pyspark/pandas/tests/test_typedef.py:239:36-64: Function call cannot be used in annotations [invalid-annotation] |
rchen152
approved these changes
Oct 6, 2026
rchen152
left a comment
Contributor
There was a problem hiding this comment.
Review automatically exported from Phabricator review in Meta.
Contributor
|
Good catch, thank you! |
Contributor
|
This pull request has been merged in cbc58eb. |
meta-codesync Bot
pushed a commit
that referenced
this pull request
Oct 7, 2026
Summary: Follow-up to #5087. In Python, built-in singleton constants and runtime objects like `NotImplemented`, `Ellipsis`, `None`, and modules do not expose their types as builtins, so users frequently write `type(...)` in type annotations (or confuse `type(MyClass)` with `type[MyClass]`). When a single-argument call to `builtins.type(...)` appears in an annotation where function calls are invalid, inspect the argument type and append a helpful suggestion to the `invalid-annotation` error message: - `type(NotImplemented)` -> ``Did you mean `types.NotImplementedType`?`` - `type(Ellipsis)` / `type(...)` -> ``Did you mean `types.EllipsisType`?`` - `type(None)` -> ``Did you mean `None`?`` - `type(some_module)` -> ``Did you mean `types.ModuleType`?`` - `type(MyClass)` -> ``Did you mean `type[MyClass]`?`` Pull Request resolved: #5120 Test Plan: Added `test_type_call_in_annotations` in `pyrefly/lib/test/annotation.rs` and ran `cargo test`. Reviewed By: stroxler Differential Revision: D123716933 fbshipit-source-id: b09c93fce8e57e267f715465e768cebd14a0767a
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary:
Python function calls are invalid type expressions in annotations (PEP 484), with native shape DSL calls as the exception in shape annotations. Previously,
allows_type_level_dsl_call()returned true for all return annotations and any type arguments nested inside them. Consequently, any ordinary function call in a return annotation (e.g.,def f() -> make_type(): ...orUnion[bool, make_type()]) was passed toparse_type_level_dsl_call, producing a misleading error:Expected a type-level DSL function, got ....This commit distinguishes shape DSL parameter contexts (
ShapeTypeArgument) from ordinary generic type arguments, and checks whether the callee is an actual registered type-level DSL function before routing to the shape DSL parser. If not in a shape context and not a DSL function, it falls back to the standard "Function call cannot be used in annotations" error.This shouldn't change type-checking behavior—only more fine-grained control for better error messages. I think that is a clearer error message, as users may be confused by the "DSL" error message, but feel free to not accept this if you disagree.
Example
Expected a type-level DSL function, got () -> type[int]Function call cannot be used in annotationsTest Plan
Added tests and run test.py