-
Notifications
You must be signed in to change notification settings - Fork 1.6k
[ty] highlight the relevant argument in type assert error messages #19426
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
4163fd8
55e01da
46591a9
6fb7eeb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| # `static_assert` | ||
|
|
||
| ## Diagnostics | ||
|
|
||
| <!-- snapshot-diagnostics --> | ||
|
|
||
| ```py | ||
| from ty_extensions import static_assert | ||
| import secrets | ||
|
|
||
| # a passing assert | ||
| static_assert(1 < 2) | ||
|
|
||
| # evaluates to False | ||
| # error: [static-assert-error] | ||
| static_assert(1 > 2) | ||
|
|
||
| # evaluates to False, with a message as the second argument | ||
| # error: [static-assert-error] | ||
| static_assert(1 > 2, "with a message") | ||
|
|
||
| # evaluates to something falsey | ||
| # error: [static-assert-error] | ||
| static_assert("") | ||
|
|
||
| # evaluates to something ambiguous | ||
| # error: [static-assert-error] | ||
| static_assert(secrets.randbelow(2)) | ||
| ``` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| --- | ||
| source: crates/ty_test/src/lib.rs | ||
| expression: snapshot | ||
| --- | ||
| --- | ||
| mdtest name: cast.md - `cast` - The redundant `cast` diagnostic | ||
| mdtest path: crates/ty_python_semantic/resources/mdtest/directives/cast.md | ||
| --- | ||
|
|
||
| # Python source files | ||
|
|
||
| ## mdtest_snippet.py | ||
|
|
||
| ``` | ||
| 1 | import secrets | ||
| 2 | from typing import cast | ||
| 3 | | ||
| 4 | # error: [redundant-cast] "Value is already of type `int`" | ||
| 5 | cast(int, secrets.randbelow(10)) | ||
| ``` | ||
|
|
||
| # Diagnostics | ||
|
|
||
| ``` | ||
| warning[redundant-cast]: Value is already of type `int` | ||
| --> src/mdtest_snippet.py:5:11 | ||
| | | ||
| 4 | # error: [redundant-cast] "Value is already of type `int`" | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this means that for a multiline cast(
int,
very_long_variable_name_splitting_the_call_over_several_lines, # type: ignore
)But this wouldn't, since the range of the suppression comment wouldn't overlap with the primary range of the diagnostic: cast( # type: ignore
int,
very_long_variable_name_splitting_the_call_over_several_lines,
)I think that would be very confusing for users, so for this reason, in #18050 (regarding the same issue, but for different diagnostics) I went with a slightly different approach of highlighting the call-arguments range with a secondary annotation but keeping the range of the entire call expression as the diagnostic's range. Some discussion in #18050 (comment) In the long term, I think it would be great if we could disentangle the concepts of "primary range to be highlighted in diagnostics" and "range in which suppression comments are deemed to apply" so that our diagnostic model doesn't require them to always be the same. But that's not something for this PR!
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For the same reasons, I'm not sure we should make any changes to |
||
| 5 | cast(int, secrets.randbelow(10)) | ||
| | ^^^^^^^^^^^^^^^^^^^^^ Inferred type is already `int` | ||
| | | ||
| info: rule `redundant-cast` is enabled by default | ||
|
|
||
| ``` | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,96 @@ | ||
| --- | ||
| source: crates/ty_test/src/lib.rs | ||
| expression: snapshot | ||
| --- | ||
| --- | ||
| mdtest name: static_assert.md - `static_assert` - Diagnostics | ||
| mdtest path: crates/ty_python_semantic/resources/mdtest/directives/static_assert.md | ||
| --- | ||
|
|
||
| # Python source files | ||
|
|
||
| ## mdtest_snippet.py | ||
|
|
||
| ``` | ||
| 1 | from ty_extensions import static_assert | ||
| 2 | import secrets | ||
| 3 | | ||
| 4 | # a passing assert | ||
| 5 | static_assert(1 < 2) | ||
| 6 | | ||
| 7 | # evaluates to False | ||
| 8 | # error: [static-assert-error] | ||
| 9 | static_assert(1 > 2) | ||
| 10 | | ||
| 11 | # evaluates to False, with a message as the second argument | ||
| 12 | # error: [static-assert-error] | ||
| 13 | static_assert(1 > 2, "with a message") | ||
| 14 | | ||
| 15 | # evaluates to something falsey | ||
| 16 | # error: [static-assert-error] | ||
| 17 | static_assert("") | ||
| 18 | | ||
| 19 | # evaluates to something ambiguous | ||
| 20 | # error: [static-assert-error] | ||
| 21 | static_assert(secrets.randbelow(2)) | ||
| ``` | ||
|
|
||
| # Diagnostics | ||
|
|
||
| ``` | ||
| error[static-assert-error]: Static assertion error: argument evaluates to `False` | ||
| --> src/mdtest_snippet.py:9:15 | ||
| | | ||
| 7 | # evaluates to False | ||
| 8 | # error: [static-assert-error] | ||
| 9 | static_assert(1 > 2) | ||
| | ^^^^^ Inferred type is `Literal[False]` | ||
| 10 | | ||
| 11 | # evaluates to False, with a message as the second argument | ||
| | | ||
| info: rule `static-assert-error` is enabled by default | ||
|
|
||
| ``` | ||
|
|
||
| ``` | ||
| error[static-assert-error]: Static assertion error: with a message | ||
| --> src/mdtest_snippet.py:13:15 | ||
| | | ||
| 11 | # evaluates to False, with a message as the second argument | ||
| 12 | # error: [static-assert-error] | ||
| 13 | static_assert(1 > 2, "with a message") | ||
| | ^^^^^ Inferred type is `Literal[False]` | ||
| 14 | | ||
| 15 | # evaluates to something falsey | ||
| | | ||
| info: rule `static-assert-error` is enabled by default | ||
|
|
||
| ``` | ||
|
|
||
| ``` | ||
| error[static-assert-error]: Static assertion error: argument of type `Literal[""]` is statically known to be falsy | ||
| --> src/mdtest_snippet.py:17:15 | ||
| | | ||
| 15 | # evaluates to something falsey | ||
| 16 | # error: [static-assert-error] | ||
| 17 | static_assert("") | ||
| | ^^ Inferred type is `Literal[""]` | ||
| 18 | | ||
| 19 | # evaluates to something ambiguous | ||
| | | ||
| info: rule `static-assert-error` is enabled by default | ||
|
|
||
| ``` | ||
|
|
||
| ``` | ||
| error[static-assert-error]: Static assertion error: argument of type `int` has an ambiguous static truthiness | ||
| --> src/mdtest_snippet.py:21:15 | ||
| | | ||
| 19 | # evaluates to something ambiguous | ||
| 20 | # error: [static-assert-error] | ||
| 21 | static_assert(secrets.randbelow(2)) | ||
| | ^^^^^^^^^^^^^^^^^^^^ Inferred type is `int` | ||
| | | ||
| info: rule `static-assert-error` is enabled by default | ||
|
|
||
| ``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this the right place for this new mdtest file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it could go into
type_api.mdwith the existing tests forstatic_assert, or if we want to keep it separate because it's all about the diagnostics rather than the functionality, then it could go somewhere underdiagnostics?