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

Calling a method of Union of two classes with class's attribute results in incompatible type error #8355

Open
Jackenmen opened this issue Feb 2, 2020 · 2 comments

Comments

@Jackenmen
Copy link

Jackenmen commented Feb 2, 2020

Honestly didn't know how to name this issue...

Issue type: Bug
Problematic code:

from typing import Union

class UserTypeA: ...
class UserTypeB: ...

class A:
    def permissions_for(self, user: UserTypeA) -> bool: ...
    
    @property
    def me(self) -> UserTypeA: ...

class B:
    def permissions_for(self, user: UserTypeB) -> bool: ...
    
    @property
    def me(self) -> UserTypeB: ...


def func(x: Union[A, B]) -> bool:
    return x.permissions_for(x.me)

Error message:

main.py:20: error: Argument 1 to "permissions_for" of "A" has incompatible type "Union[UserTypeA, UserTypeB]"; expected "UserTypeA"
main.py:20: error: Argument 1 to "permissions_for" of "B" has incompatible type "Union[UserTypeA, UserTypeB]"; expected "UserTypeB"

Expected behaviour:
No error as x.me matches the type expected by x.permissions_for - if instance of A is passed x.me will have type UserTypeA and x.permissions_for will expect UserTypeA and same for instance of B.

Also, if func looks like this, the errors are gone so if mypy could infer this without isinstance it would be great:

def func(x: Union[A, B]) -> bool:
    if isinstance(x, A):
        return x.permissions_for(x.me)
    else:
        return x.permissions_for(x.me)

Python version:: 3.8.1
Mypy version: 0.761, occurs on master as well
Mypy flags: No flags

@JukkaL
Copy link
Collaborator

JukkaL commented Feb 4, 2020

This is probably too difficult for mypy to understand, but leaving open as a low-priority issue in case somebody comes up with a simple way to support this.

@intgr
Copy link
Contributor

intgr commented Feb 25, 2020

Meanwhile you could solve this by creating a Protocol for the common methods shared between A and B, and taking that as argument.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants