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

How do you implement type-checking with methods for classes that inherit from NamedTuple? #2954

Closed
knowsuchagency opened this issue Mar 3, 2017 · 4 comments

Comments

@knowsuchagency
Copy link

Could it be related to the bug mentioned in #1987 ?

class A:
    def __init__(self, x: int) -> None:
        self.x = x

    # mypy seems perfectly happy with this
    def __add__(self, other: 'A') -> 'A':
        return type(self)(self.x + other.x)

    def __str__(self) -> str:
        return f'A(x={self.x})'


class B(NamedTuple('B', [('x', int)])):

    # error: Argument 1 of "__add__" incompatible with supertype "tuple"
    def __add__(self, other: 'B') -> 'B':
        return type(self)(self.x + other.x)
@gvanrossum
Copy link
Member

gvanrossum commented Mar 3, 2017 via email

@knowsuchagency
Copy link
Author

Is there a way to use the method signature of the class itself?

It would be nice to inherit the functionality of the NamedTuple class while being able to perform type-checking on the methods that are overridden.

It's just not clear to me how one would do that.

@gvanrossum
Copy link
Member

I'm not 100% sure what you're trying to accomplish, but on the basis of your initial example I'm guessing you want to redefine + for class B to implement element-wise addition on instances of B. The reason mypy doesn't support this by default is something called the "Liskov substitution principle" (you can Google it for an explanation).

However there's a work-around: put # type: ignore on the line that produces the error (the def __add__ line). This is not sound but it will do what you want as long as you never pass a B instance to code that assumes it's a tuple and attempts tuple concatenation on it.

@knowsuchagency
Copy link
Author

I wasn't trying to do anything specific, per se. I was having a discussion about NamedTuples in Python and nominal vs structural typing and I came across this behavior when reading this person's comment.

Thank you for taking the time to provide a thoughtful and helpful explanation, Benevolent Dictator!!

I'll be sure to pass on the knowledge in case others have a similar question.

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

No branches or pull requests

2 participants