Skip to content

False positive TCH003 fix for singledispatch functions with type annotations. #11520

@wence-

Description

@wence-

Consider:

from __future__ import annotations

from functools import singledispatch
from typing import Any

from collections.abc import MutableMapping


@singledispatch
def foo(x: Any, y: MutableMapping) -> int:
    raise NotImplementedError


@foo.register
def _(x: int, y: MutableMapping) -> int:
    return x

With the following ruff configuration

[tool.ruff]
target-version = "py39"

[tool.ruff.lint]
select = ["TCH"]

[tool.ruff.lint.flake8-type-checking]
strict = true

ruff suggests that (TCH003) MutableMapping be moved into a TYPE_CHECKING block, however, this is an invalid fix since the singledispatch registration needs access to the types at runtime.

$ python --version
Python 3.10.14
$ ruff --version
0.4.5
$ python bug.py # no issues
$ ruff check bug.py
bug.py:6:29: TCH003 Move standard library import `collections.abc.MutableMapping` into a type-checking block
Found 1 error.
No fixes available (1 hidden fix can be enabled with the `--unsafe-fixes` option).
$ ruff check --unsafe-fixes bug.py
Found 1 error (1 fixed, 0 remaining).
$ python bug.py
Traceback (most recent call last):
  File "/home/coder/doodles/python/ruff-check/bug.py", line 17, in <module>
    def _(x: int, y: MutableMapping) -> int:
  File "/home/coder/.conda/envs/rapids/lib/python3.10/functools.py", line 871, in register
    argname, cls = next(iter(get_type_hints(func).items()))
  File "/home/coder/.conda/envs/rapids/lib/python3.10/typing.py", line 1871, in get_type_hints
    value = _eval_type(value, globalns, localns)
  File "/home/coder/.conda/envs/rapids/lib/python3.10/typing.py", line 327, in _eval_type
    return t._evaluate(globalns, localns, recursive_guard)
  File "/home/coder/.conda/envs/rapids/lib/python3.10/typing.py", line 694, in _evaluate
    eval(self.__forward_code__, globalns, localns),
  File "<string>", line 1, in <module>
NameError: name 'MutableMapping' is not defined

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions