python / mypy

Optional static typing for Python
https://www.mypy-lang.org/
Other
18.26k stars 2.79k forks source link

With `--disallow-any-decorated`, `Any` detection logic changes w/wo decorator #15211

Open 243f6a8885a308d313198a2e037 opened 1 year ago

243f6a8885a308d313198a2e037 commented 1 year ago

Bug Report

(A clear and concise description of what the bug is.)

We expect that adding a decorator to a method will never produce a new mypy error unless the decorator itself introduces a new Any annotation, i.e. expect no new error if the decorator itself does not introduce any additional Any.

We also believe that it is difficult to call this behavior a bug. The behavior of the option itself seems self-evident in its own way.

But we would expect a situation where simply applying a harmless decorator would not change the presence or absence of errors.

To Reproduce

Here is a test case.

[case testDisallowAnyDecoratedShouldNeverAffect]
# flags: --disallow-any-decorated

import dataclasses
from typing import Any, Callable

from typing_extensions import TypedDict, TypeVar

class CtxAny(TypedDict):
    place: Any

CallableT = TypeVar("CallableT")

def custom_decorator(func: CallableT) -> CallableT:
    return func

class Something:
    # No error
    def do(self, ctx: CtxAny) -> None:
        pass

    @classmethod
    # This emits an error, unexpected.
    def do_classmethod(cls, ctx: CtxAny) -> None:  # E: Type of decorated function contains type "Any" ("Callable[[Type[Something], CtxAny], None]")
        pass

    @custom_decorator
    # This emits an error, unexpected.
    def do_custom_decorator(self, ctx: CtxAny) -> None:  # E: Type of decorated function contains type "Any" ("Callable[[Something, CtxAny], None]")
        pass
[builtins fixtures/classmethod.pyi]

Expected Behavior

We expect do and others to be the same error-condition.

i.e. one of:

Actual Behavior

As shown in reproduction code.

Your Environment

243f6a8885a308d313198a2e037 commented 1 year ago

Maybe using --disallow-any-expr --disallow-any-explicit without --disallow-any-decorated is one answer?

→ These options are too strict for real application ... :cry: