Skip to content
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

The generic type of an inner function cannot be made to match the generic type of an enclosing function #8696

Closed
NeilGirdhar opened this issue Apr 19, 2020 · 7 comments
Labels
bug mypy got something wrong diagnostics priority-2-low

Comments

@NeilGirdhar
Copy link
Contributor

NeilGirdhar commented Apr 19, 2020

With the following example:

from typing import Callable, Generic, Type, TypeVar

XType = TypeVar('XType', bound=int)


class C(Generic[XType]):
    def f(self, x_init: XType) -> XType:
        return x_init


def combinator(c_cls: Type[C[XType]]) -> Callable[[C[XType], XType], XType]:
    old_f = c_cls.f

    def new_f(c: C[XType], x_init: XType) -> XType:
        return old_f(c, x_init)

    return new_f

MyPy 0.910 says:

a.py:15: error: Incompatible return value type (got "XType", expected "XType")
a.py:15: error: Argument 1 has incompatible type "C[XType]"; expected "C[XType]"
a.py:15: error: Argument 2 has incompatible type "XType"; expected "XType"
@NeilGirdhar NeilGirdhar changed the title How can identical types be incompatible in MyPy? How can identical types be incompatible? Apr 19, 2020
@msullivan
Copy link
Collaborator

Ugh! This is a bad error message, and pretty confusing.

I think that the issue here is that the inner function binds those type variables separately (but maybe it shouldn't?), which is why there is a type mismatch: they are different XTypes. But it is definitely a bug in the error message!

@msullivan msullivan changed the title How can identical types be incompatible? Bad error message with nested functions with shadowed type variables Apr 29, 2020
@msullivan msullivan added bug mypy got something wrong diagnostics priority-2-low labels Apr 29, 2020
@NeilGirdhar
Copy link
Contributor Author

NeilGirdhar commented Apr 29, 2020

@msullivan Thanks for taking a look. I ended up redesigning this, so it's not a priority for me anymore. Out of curiosity, how should I have annotated this?

However, thank you, MyPy people, for the great project. It's really useful!

@NicolaDonelli
Copy link

NicolaDonelli commented Aug 30, 2021

Sorry for resuming this old issue but I just stumbled in (what I believe is) this same situation and I could not find a solution.

My code is:

from abc import ABC, abstractmethod
from typing import TypeVar, Iterable, Iterator

T = TypeVar('T')


class MyABC(ABC):

    @property
    @abstractmethod
    def items(self) -> Iterable[T]: ...

    def __iter__(self) -> Iterator[T]:
        for item in self.items:
            yield item

and, while running mypy command (version 0.910), I got:

 error: Incompatible types in "yield" (actual type "T", expected type "T")

I admit I am not completely sure it is the same issue as the one reported by @NeilGirdhar and that @msullivan suggested being due to the fact that "they are different T type", but it seemed so and I couldn't find a way to change my code to avoid this error.
In particular, I need to bind the type of the elements in 'items' to the YieldType of 'iter' , but I didn't find the correct solution to do that.

@NeilGirdhar
Copy link
Contributor Author

NeilGirdhar commented Aug 30, 2021

@NicolaDonelli Did you try inheriting from Generic[T]? (And you should probably inherit from Iterable[T] also, and replace the for loop with a simple yield from self.items.

from abc import abstractmethod
from typing import TypeVar, Iterable, Iterator, Generic
from collections.abc import Iterable

T = TypeVar('T')


class MyABC(Iterable[T], Generic[T]):
    @property
    @abstractmethod
    def items(self) -> Iterable[T]: ...

    def __iter__(self) -> Iterator[T]:
        yield from self.items

It may be worth considering filing an issue to improve the error message for this case.

@NicolaDonelli
Copy link

NicolaDonelli commented Aug 30, 2021

@NeilGirdhar, nope I didn't try before and effectively your proposed solution works like a charm, thanks a lot!

For what it takes the issue about the error message, would you prefer me to open it or you'd prefer to open it yourself?

@NeilGirdhar
Copy link
Contributor Author

NeilGirdhar commented Aug 31, 2021

thanks a lot!

You're very welcome.

would you prefer me to open it or you'd prefer to open it yourself?

I'm not opening it.

@NeilGirdhar NeilGirdhar changed the title Bad error message with nested functions with shadowed type variables The generic type of an inner function cannot be made to match the generic type of an enclosing function Dec 2, 2021
@NeilGirdhar
Copy link
Contributor Author

Looks like the error message is fixed!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong diagnostics priority-2-low
Projects
None yet
Development

No branches or pull requests

3 participants