Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions conformance/results/mypy/directives_type_ignore.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@ Does not honor "# type: ignore" comment if comment includes additional text.
output = """
directives_type_ignore.py:11: error: Invalid "type: ignore" comment [syntax]
directives_type_ignore.py:11: error: Incompatible types in assignment (expression has type "str", variable has type "int") [assignment]
directives_type_ignore.py:14: error: Incompatible types in assignment (expression has type "str", variable has type "int") [assignment]
directives_type_ignore.py:14: note: Error code "assignment" not covered by "type: ignore" comment
directives_type_ignore.py:16: error: Incompatible types in assignment (expression has type "str", variable has type "int") [assignment]
directives_type_ignore.py:16: note: Error code "assignment" not covered by "type: ignore" comment
"""
conformance_automated = "Fail"
errors_diff = """
Line 11: Unexpected errors ['directives_type_ignore.py:11: error: Invalid "type: ignore" comment [syntax]', 'directives_type_ignore.py:11: error: Incompatible types in assignment (expression has type "str", variable has type "int") [assignment]']
Line 14: Unexpected errors ['directives_type_ignore.py:14: error: Incompatible types in assignment (expression has type "str", variable has type "int") [assignment]']
"""
4 changes: 2 additions & 2 deletions conformance/results/results.html
Original file line number Diff line number Diff line change
Expand Up @@ -1191,9 +1191,9 @@ <h3>Python Type System Conformance Test Results</h3>
<tr><th class="column col1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;directives_type_ignore</th>
<th class="column col2 partially-conformant"><div class="hover-text">Partial<span class="tooltip-text" id="bottom"><p>Does not honor "# type: ignore" comment if comment includes additional text.</p></span></div></th>
<th class="column col2 conformant">Pass</th>
<th class="column col2 partially-conformant"><div class="hover-text">Partial<span class="tooltip-text" id="bottom"><p>Does not honor "# type: ignore" comment if comment includes additional text.</p></span></div></th>
<th class="column col2 conformant">Pass</th>
<th class="column col2 partially-conformant"><div class="hover-text">Partial<span class="tooltip-text" id="bottom"><p>Treats `# type: ignore[error-code]` as only ignoring errors that match the error code `error-code`.</p></span></div></th>
<th class="column col2 conformant">Pass</th>
<th class="column col2 conformant">Pass</th>
</tr>
<tr><th class="column col1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;directives_type_ignore_file1</th>
<th class="column col2 conformant">Pass</th>
Expand Down
9 changes: 2 additions & 7 deletions conformance/results/ty/directives_type_ignore.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
conformance_automated = "Fail"
conformant = "Partial"
notes = """
Treats `# type: ignore[error-code]` as only ignoring errors that match the error code `error-code`.
"""
conformance_automated = "Pass"
errors_diff = """
Line 14: Unexpected errors ['directives_type_ignore.py:14:10: error[invalid-assignment] Object of type `Literal[""]` is not assignable to `int`']
"""
output = """
directives_type_ignore.py:14:10: error[invalid-assignment] Object of type `Literal[""]` is not assignable to `int`
directives_type_ignore.py:16:10: error[invalid-assignment] Object of type `Literal[""]` is not assignable to `int`
"""
11 changes: 3 additions & 8 deletions conformance/results/zuban/directives_type_ignore.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
conformant = "Partial"
notes = """
Does not honor "# type: ignore" comment if comment includes additional text.
"""
conformance_automated = "Fail"
conformance_automated = "Pass"
errors_diff = """
Line 14: Unexpected errors ['directives_type_ignore.py:14: error: Incompatible types in assignment (expression has type "str", variable has type "int") [assignment]']
"""
output = """
directives_type_ignore.py:14: error: Incompatible types in assignment (expression has type "str", variable has type "int") [assignment]
directives_type_ignore.py:14: note: Error code "assignment" not covered by "type: ignore" comment
directives_type_ignore.py:16: error: Incompatible types in assignment (expression has type "str", variable has type "int") [assignment]
directives_type_ignore.py:16: note: Error code "assignment" not covered by "type: ignore" comment
"""
6 changes: 4 additions & 2 deletions conformance/tests/directives_type_ignore.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@
# The following type violation should be suppressed.
y: int = "" # type: ignore - additional stuff

# The following type violation should be suppressed.
z: int = "" # type: ignore[additional_stuff]
# The following type violation may be suppressed, depending whether the
# type checker uses the error code `assignment` for invalid assignments,
# and/or how it treats unknown error codes.
Comment on lines +13 to +15
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I know I'm editing myself here, but this comment needs another update now that the next line is using a made-up error code that no type checker would ever use:

Suggested change
# The following type violation may be suppressed, depending whether the
# type checker uses the error code `assignment` for invalid assignments,
# and/or how it treats unknown error codes.
# The following type violation may be suppressed, if the type checker
# actually uses the code `an-empty-str-is-not-an-int` (unlikely!), or if
# it treats unknown codes as blanket ignores.

z: int = "" # type: ignore[an-empty-str-is-not-an-int] # E?

# > In some cases, linting tools or other comments may be needed on the same
# > line as a type comment. In these cases, the type comment should be before
Expand Down
9 changes: 9 additions & 0 deletions docs/spec/directives.rst
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,15 @@ other comments and linting markers:

# type: ignore # <comment or other marker>

The form ``# type: ignore[...]`` may be used to suppress only type errors with a
given error code, though support for this is optional and may vary by type checker:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

What about also documenting that multiple error codes can be given (comma-separated), and unrecognized error codes should be ignored, if a type checker supports ignoring errors based on specific error code, as @ilevkivskyi suggested here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Are there any other opinions on this? I'm pretty open to changes here.

I personally think that the comma separated form doesn't need to be specified explicitly.

unrecognized error codes should be ignored, if a type checker supports ignoring errors based on specific error code

Does this mean that Mypy would need to ignore the error code "undefined"? Currently it adds errors at least when using --warn-unused-ignores: https://mypy-play.net/?mypy=latest&python=3.12&flags=warn-unused-ignores&gist=27ebc9511f193a9f348b0235412cbcc9

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I personally think that the approach outlined by @ilevkivskyi is the right one for multi-type-checker interoperability (much better than requiring totally separate ignore comments for each type checker), and I would be happy to fully specify it. But that would be a specification change that puts pyright and pyrefly out of conformance. If we did that, then I think the fulI behavior, including multiple comma separated codes, should be specified. I guess maybe we need feedback at least from pyrefly here: is the "always blanket ignore" behavior pyrefly's UX preference, or just something that was done to satisfy the previous conformance suite requirements?

But I think as long as the specification here is looser, as currently written (to accommodate both the pyright/pyrefly behavior and the mypy/zuban/ty behavior), it's not really important to document the multiple-error-codes handling, since effectively all this spec is now saying is that type checkers can do whatever they want with the information inside the brackets.

(Either way, I don't think the spec should _require_that type checkers be silent about unknown codes; it should be OK to warn users about them, as mypy does with --warn-unused-ignores. This is better behavior for users who aren't using multiple type checkers. Ideally users in multi-type-checker scenarios can turn off that warning if they don't want it.)

I'm happy with the current state of this PR as a first step, at least.


- Given ``# type: ignore[my_code1]``, a type checker may ignore the error code
``my_code1`` and choose to treat this form as equivalent to ``# type: ignore``.
- Alternatively, given ``# type: ignore[my_code1]`` a type checker may suppress the
error only if the error cause matches the error code ``my_code1``.
- A bare ``# type: ignore`` must always suppress all type errors.

.. _`cast`:

``cast()``
Expand Down