Skip to content

TypeVar error #12882

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

Closed
julzt0244 opened this issue May 27, 2022 · 1 comment · Fixed by #19183
Closed

TypeVar error #12882

julzt0244 opened this issue May 27, 2022 · 1 comment · Fixed by #19183
Labels
bug mypy got something wrong topic-type-narrowing Conditional type narrowing / binder

Comments

@julzt0244
Copy link

julzt0244 commented May 27, 2022

Following up on my previous issue, it seems TypeVars are bugged and do not allow for more specific subclasses of one of the bound types specific, unlike using Unions alone?

See the 2 generic types represented by the variables "CombinedTypes" and "T"

Environment

  • Mypy version used: 0.950 and 0.960
  • Mypy command-line flags: None
  • Mypy configuration options from mypy.ini (and other config files): None
  • Python version used: Python 3.10.4
  • Operating system and version: Windows 10 (Version 21H2)

Full simplified test code to reproduce the bug

from abc import ABCMeta
from typing import Generic, TypeVar, Union


class BaseEngine(metaclass=ABCMeta):
    pass


class BaseEngineVariantA(BaseEngine):
    pass


class BaseEngineVariantB(BaseEngine):
    pass


class VariantAConcreteEngine(BaseEngineVariantA):
    pass


CombinedTypes = Union[BaseEngineVariantA, BaseEngineVariantB]
T = TypeVar('T', bound=CombinedTypes)


class IBase(Generic[T], metaclass=ABCMeta):
    def __init__(self, engine: T):
        self.engine = engine


class IAction(IBase[T], metaclass=ABCMeta):
    pass


class ErrorIfUsingTypeVar(IBase[T]):
    def __init__(self, something: T, actions_injected: type[IAction[T]]) -> None:
        self.something = something
        self.actions_injected = actions_injected

    def foo(self) -> None:
        if not isinstance(self.something, VariantAConcreteEngine):
            raise Exception("HI")

        self.actions_injected(self.something)  # Gives a mypy error of - error: Argument 1 to "IAction" has incompatible type "VariantAConcreteEngine"; expected "T"


class WorksFineUsingUnionsAlone(IBase[CombinedTypes]):
    def __init__(self, something: CombinedTypes, actions_injected: type[IAction[CombinedTypes]]) -> None:
        self.something = something
        self.actions_injected = actions_injected

    def foo(self) -> None:
        if not isinstance(self.something, VariantAConcreteEngine):
            raise Exception("HI")

        self.actions_injected(self.something)  # No error if using unions alone

@julzt0244 julzt0244 added the bug mypy got something wrong label May 27, 2022
@JelleZijlstra JelleZijlstra added the topic-type-narrowing Conditional type narrowing / binder label May 27, 2022
@JelleZijlstra
Copy link
Member

I guess the issue is that the isinstance() call narrows self.something to type VariantAConcreteEngine and the fact that it's of type T is lost.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong topic-type-narrowing Conditional type narrowing / binder
Projects
None yet
2 participants