python / mypy

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

callable.__call__ leads to Callable is not callable #5079

Open ethanhs opened 6 years ago

ethanhs commented 6 years ago

In a quite amusing, confusing error:

mypy -c "callable.__call__"
# error: Callable[[Iterable[object]], bool] is not callable
ezyang commented 5 years ago

I'm affected by this too!

ethanhs commented 5 years ago

@ezyang, do you have some real world code that triggers this?

ezyang commented 5 years ago

Actually, it turns out my bug is unrelated (and I was trying to (incorrectly) use __call__ to work around it). I'll file a different bug

AlexWaygood commented 2 years ago

The error message on 0.941 is arguably even worse:

"Callable[[object], TypeGuard[Callable[..., object]]]" not callable

But it doesn't seem like there's much real-world code affected by this, so I'm lowering the priority level.

jmmaa commented 2 years ago

any updates to this problem?

mastercoms commented 1 year ago

I am experiencing this problem in this PR: https://github.com/tiangolo/fastapi/pull/5461

randolf-scholz commented 1 year ago

I have some real-world example: I am writing a lazy function class, that takes a Callable and all of it's *args and **kwargs, but delays evaluation. To write a nice __repr__, I want to read the __annotations__, if they exist, to hint at what kind of object the function will return (i.e. something along the lines of LazyFunction<int> if the given function returns int.)

Now, regular functions and callable classes store __annotations__ at different places, hence it runs into this error

from types import FunctionType
from typing import Callable

def show_annotations(func: Callable) -> None:
    if isinstance(func, FunctionType):
        print(func.__annotations__)
    else:
        print(func.__call__.__annotations__)  # ✘ error [operator]

class Foo:
    def __call__(self) -> None:
        pass

def foo() -> None:
    pass

show_annotations(foo)
show_annotations(Foo())
JelleZijlstra commented 1 year ago

@randolf-scholz note that your code isn't type-safe as there is no guarantee that the __call__ attribute will itself have .__annotations__; it may be another non-function callable.

Obviously the mypy error at issue here is still a bug.

finite-state-machine commented 10 months ago

This applies to any callable, as far as I can see.

Here's a simple test case: gist

def some_function() -> None:
    pass

some_function.__call__
        # error: "Callable[[], None]" not callable  [operator]