# Ignore mypy-specific type errors

**URL:** <https://discuss.python.org/t/ignore-mypy-specific-type-errors/58535>\
**Category:** Typing\
**Tags:** typing\
**Created:** [July 18, 2024, 8:47am UTC](https://discuss.python.org/t/ignore-mypy-specific-type-errors/58535 "2024-07-18T08:47:13Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![srittau](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/srittau/32/237_2.png) [@srittau](https://discuss.python.org/u/srittau)\
**Post date:** [July 18, 2024, 8:47am UTC](https://discuss.python.org/t/ignore-mypy-specific-type-errors/58535/1 "2024-07-18T08:47:13Z")

</div>

(There’s previous discussion about this in mypy’s GitHub issues: [Support `mypy: ignore` inline comments to suppress mypy errors · Issue #12358 · python/mypy · GitHub](https://github.com/python/mypy/issues/12358))

Currently, there is no way to ignore mypy-specific type errors. It’s possible to ignore typing errors for all type checkers using `# type: ignore` and pyright supports ignore pyright-specific errors using `# pyright: ignore`:

```python
x: int = "" # type: ignore # works for all type checkers
assert_type(3**4, int) # pyright: ignore
# assert_type(2**4, Literal[16]) # no way to ignore this for mypy only

```

There have been two suggestions to solve this problem:

1. Introduce a `mypy: ignore` directive. The main problem is that mypy uses the stdlib `ast` module to parse Python files, meaning that `ast` would need to support this somehow. @NeilGirdhar suggested to add a flag to support this to `ast` in [this thread](https://discuss.python.org/t/add-comments-parsing-flag-to-ast-parse/23461) and [gh-101494](https://github.com/python/cpython/issues/101494).
2. Extend the `# type: ignore` syntax to allow type-checker specific ignores. Currently, `# type: ignore` is underspecified [in the Typing Specification](https://typing.readthedocs.io/en/latest/spec/directives.html#type-ignore-comments) as mypy already extends the syntax by allowing constructs like `# type: ignore[foo,bar]` to ignore specific error codes. This syntax could be properly spec’ed and extended.

Personally, I like the second solution better, especially since – apart from type checker changes – it only requires a change to the Typing Spec, instead of changes to `ast` for a more esoteric feature.

---

<div class="post-metadata">

**Author:** ![erictraut](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/erictraut/32/15190_2.png) [@erictraut](https://discuss.python.org/u/erictraut)\
**Post date:** [July 18, 2024, 2:21pm UTC](https://discuss.python.org/t/ignore-mypy-specific-type-errors/58535/2 "2024-07-18T14:21:20Z")

</div>

I prefer the first option. Option 2 will cause backward compatibility problems and significant churn for some pyright users. Mypy really should have its own way of disabling mypy-specific errors.

I’m not convinced that mypy needs a change to the ast to support a mypy-specific directive. It has been suggested in other threads that it could use a combination of the ast (which contains file locations in the ast nodes) and the original file text to retrieve end-of-line comments. Has anyone tried to implement this? I think this should at least be prototyped before we consider extending the existing hack in the ast module or contemplate changing the typing spec to accommodate mypy’s current implementation limitations.

Another option to consider is for mypy to incorporate its own copy of the peg parser and ast. This is a bigger change, but it would allow mypy to support newer language features when running on older versions of Python. Mypy’s current dependency on the ast module prevents us from leveraging newer language features (like PEP 695) in stubs.

---

<div class="post-metadata">

**Author:** ![srittau](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/srittau/32/237_2.png) [@srittau](https://discuss.python.org/u/srittau)\
**Post date:** [July 18, 2024, 2:36pm UTC](https://discuss.python.org/t/ignore-mypy-specific-type-errors/58535/3 "2024-07-18T14:36:50Z")

</div>

> [@erictraut](#):
>
> Option 2 will cause backward compatibility problems and significant churn for some pyright users.

I’m interested in how this would cause backward compatibility problems? I’m not even sure that pyright would need to change.

> [@erictraut](#):
>
> Another option to consider is for mypy to incorporate its own copy of the peg parser and ast. This is a bigger change, but it would allow mypy to support newer language features when running on older versions of Python. Mypy’s current dependency on the ast module prevents us from leveraging newer language features (like PEP 695) in stubs.

This is indeed an ongoing concern with mypy. If we’d change the `ast` module, mypy would only be able to leverage this feature when dropping support for Python 3.13, many years in the future. mypy shipping its own copy of the `ast` module (similar how it used to used `typed_ast` in the past) would be helpful, but the last time I looked at it, the `ast` module is deeply connected to the rest of the Python interpreter and the build system, so “freeing” it (and keeping it in sync) would be a major undertaking.

---

<div class="post-metadata">

**Author:** ![erictraut](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/erictraut/32/15190_2.png) [@erictraut](https://discuss.python.org/u/erictraut)\
**Post date:** [July 18, 2024, 3:03pm UTC](https://discuss.python.org/t/ignore-mypy-specific-type-errors/58535/4 "2024-07-18T15:03:02Z")

</div>

> [@srittau](#):
>
> I’m interested in how this would cause backward compatibility problems? I’m not even sure that pyright would need to change.

Pyright follows the current typing spec. If it sees a `# type: ignore` on a line (regardless of what comes after the `# type: ignore`) it suppresses all type checking diagnostics on that line. If the typing spec were to change and indicate that type checkers now need to conditionally suppress subsets of diagnostics on a line if a `# type: ignore` is followed by square brackets, then pyright’s behavior would need to change accordingly. If the square brackets were to contain only items that pyright doesn’t know about, it would presumably not suppress any diagnostics on that line, which would be a change in behavior from today. This would further trigger `reportUnnecessaryTypeIgnoreComment` diagnostics.

I’ll also note that the type checker-specific form `# pyright: ignore[x, y, z]` allows pyright to tell developers they have misspelled one of the rules listed in square brackets, whereas with `# type: ignore[x, y, z]` it would need to simply ignore any potential misspellings because they could be rules that apply to other type checkers — unless the new syntax allowed for some namespace mechanism like `# type: ignore[mypy:assignment, pyright:reportAssignmentType]`.

---

<div class="post-metadata">

**Author:** ![srittau](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/srittau/32/237_2.png) [@srittau](https://discuss.python.org/u/srittau)\
**Post date:** [July 18, 2024, 4:35pm UTC](https://discuss.python.org/t/ignore-mypy-specific-type-errors/58535/5 "2024-07-18T16:35:26Z")

</div>

> [@erictraut](#):
>
> Pyright follows the current typing spec. If it sees a `# type: ignore` on a line (regardless of what comes after the `# type: ignore`) it suppresses all type checking diagnostics on that line.

That’s not how I interpret the current wording (which is why I said the section was “underspecified” above):

> The special comment `# type: ignore` is used to silence type checker errors.

I would argue that the behavior of `# type: ignore[...]` is unspecified. That said, pyright’s interpretation is sensible. Maybe as a first step we could complete the specification to match real world usage. I’d need to look at the behavior of current type checkers to make a concrete proposal, but something along the lines that type checkers can narrow the ignored errors using type checker-specific error codes using the syntax currently used by mypy. Unknown errors codes should turn this into an unrestricted `# type: ignore`. Type checkers may warn about that.

And then in a second step build on that by extending the syntax, for example by using the prefix notation you suggested.

---

<div class="post-metadata">

**Author:** ![erictraut](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/erictraut/32/15190_2.png) [@erictraut](https://discuss.python.org/u/erictraut)\
**Post date:** [July 18, 2024, 5:08pm UTC](https://discuss.python.org/t/ignore-mypy-specific-type-errors/58535/6 "2024-07-18T17:08:14Z")

</div>

I think it would be better for mypy to add support for its own suppression comment. Other type checkers already do this. I don’t want to codify a mechanism that is less usable just because mypy has a current internal implementation limitation. As I mentioned above, I suspect this limitation is artificial and could be worked around.

> [@srittau](#):
>
> Unknown errors codes should turn this into an unrestricted `# type: ignore`.

That’s a good suggestion if we go with option 2. It would retain current pyright behaviors and therefore eliminate one of my objections to the proposal. I still prefer option 1.

> [@srittau](#):
>
> Type checkers may warn about that.

Probably not. There would be no way to suppress such a warning.

---

<div class="post-metadata">

**Author:** ![InSync](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/insync/32/12531_2.png) [@InSync](https://discuss.python.org/u/InSync)\
**Post date:** [July 24, 2024, 12:44pm UTC](https://discuss.python.org/t/ignore-mypy-specific-type-errors/58535/7 "2024-07-24T12:44:22Z")

</div>

> [@srittau](#):
>
> Extend the `# type: ignore` syntax to allow type-checker specific ignores.

PEP 8 says that a line should be no longer than 79 characters.

An average [Mypy error code](https://github.com/python/mypy/blob/db9837fa240918fa90f2d9a3952314bd3207ed20/mypy/errorcodes.py) is 13 characters long:

This is much shorter than that of, say, [Pyright](https://github.com/microsoft/pyright/blob/258e2754bdd7d9c376e4733887d6f79bf5786919/packages/vscode-pyright/schemas/pyrightconfig.schema.json) (~24, 18 if `report` can somehow be excluded), but it will do for an approximation.

```pycon
>>> import mypy.errorcodes as m
>>> l = [ec.code for ec in vars(m).values() if isinstance(ec, m.ErrorCode)]
>>> sum(len(c) for c in l) / len(l)
12.55072463768116

```

Thus, a properly formatted ignore comment takes 18 + 13 = 31 characters.

```python
  # type: ignore[abcdefghijklm]

```

OOP is common, so let’s say I’m inside a method, at the second indentation level; that takes 8 more.

Since I’m inside a method, chances are that I’m working with an attribute of `self`. I aim for readability, so the length of that attribute’s name is about 10. Accessing an attribute by itself generally doesn’t do anything useful, so it must be a part of a method call (`()`), an assignment (`=` and 2 surrounding spaces) or a function call (`()` + 10).

If this hypothetical syntax allows differentiating type checkers, by the principle of least astonishment it must use the type checker’s name, which costs about 4 (`mypy`, `pyre`) to 7 (`pyright`, `pycharm`) characters, as well as a separator character to separate that name and the corresponding rule (e.g. `mypy:override`).

All of these leave me with at best (79 - 39 - 15) - 2 - 5 = 18 characters and at worst 25 - 12 - 8 = 5 characters. Remember, I’m still at the second indent level. How would I be able to respect the limit while also making use of the new syntax if I needed to ignore a second rule by another type checker?

Option 1 is the way to go.
