-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
RFC: a type comment to ignore expected errors #8655
Comments
Another option is to write the test as |
But then wouldn't that prevent the test from executing the way it was intended? The exception would no longer be raised and the test would fail, right? I'm just learning Python, so maybe I'm wrong. |
No, the
The cast function tells mypy that we know this variable is actually a If you wanted to actually convert the type, you would use
|
That isn't an ideal solution. It doesn't solve the underlying problem, which is that the type-checker should enforce that there is a type error on the given line, and only raise an error to the user if there is no longer a type error on that line. Using |
@mwgamble there is a |
But that's all a roundabout messy way of solving the problem, rather than supporting something similar to what Typescript has supported for quite a while now. |
Ohhh, how long has that been around for? I can't find it listed in the docs. |
Sorry, it's actually |
Oh, yes, I have used that option. :P |
For others interested in this feature, pyright has a configuration option: |
@rattrayalex mypy has an equivalent flag (https://mypy.readthedocs.io/en/stable/command_line.html#cmdoption-mypy-warn-unused-ignores), but as the OP explains, it does not fully cover the use case. |
Problem
Python is optionally typed, and a lot of type-annotated libraries also add runtime type checks to prevent misuse by users who do not type-check their own code. For example:
If the library then wants to test this check, mypy complains:
The error is legitimate and expected, but cannot be left alone because it causes mypy to fail. The usual way to fix this is to tell mypy to ignore it:
This solution for the most part works great, but is not ideal:
One problem with it is that if something in the type of the line changes unintentionally such that the type error no longer triggers, the
type: ignore
comment doesn't do anything, silently. Hence it is not a good vehicle for doing "type-level assertions".mypy provides also solution for this unused-ignore problem -- the
warn_unused_ignores
option. But this in itself is also not ideal: it can be specified either globally or per-file, but that is too coarse. Sometimes there aretype: ignores
which only conditionally trigger, depending on e.g. python version, dependency version or platform, sowarn_unused_ignores
cannot be set.Another problem with using
type: ignore
for "type-level assertions" is that the intent is not self-evident - it is not immediately clear whether it is meant as an assertion or as a workaround/TODO/I-know-this-is-bad-but-I-am-doing-it-anyway.When working on adding (inline) type annotations to the pytest project, and also in my personal projects, I have wanted this often.
Solution
Add a new
type: ignore-expected
directive (also accepts error codestype: ignore-expected[arg-type,operator]
).Semantically, this directive is exactly the same as
type: ignore
, except that it triggers an error about being unused even ifwarn_unused_ignores
is not set, and has a differentiated error messageunused 'type: ignore-expected' comment
.For type-errors that are "asserted"/expected,
type: ignore-expected
should be used. For other cases,type: ignore
should continue to be used.Practical matters
A POC implementation is available at https://github.com/bluetech/mypy/tree/type-ignore-expected. The implementation is not polished, and is lacking comprehensive tests and documentation, but is meant to show feasibility.
Above I proposed to add a new directive. The existing directive
type: ignore
is actually parsed and is a part of the Python AST (since Python 3.8, or intyped-ast
for earlier versions). It is represented as aTypeIgnore
AST node (link). If this idea is accepted, then hopefully theTypeIgnore
node can be extended with aexpected: bool
attribute. In the mean time, due to the loose why the comment is apparently parsed by the parser, it is possible to handle any way in a hacky way, as the PR does. Such an approach can also be used to provide seamless backward compatibility.Prior work
When researching this I have found out that TypeScript has just added support for exactly this (not in a released version yet at the time of writing), see https://devblogs.microsoft.com/typescript/announcing-typescript-3-9-beta/#ts-expect-error-comments. The equivalent to their directive name would be
type: expect-error[...]
, but is otherwise the same as far as I can tell.The text was updated successfully, but these errors were encountered: