-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Allow subtypes to define more overloads than their supertype #3263
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
Changes from 1 commit
d1ec354
49e7b22
b8a8304
2ca49fc
eb36c41
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1419,23 +1419,6 @@ class B(A): | |
[out] | ||
tmp/foo.pyi:8: error: Signature of "__add__" incompatible with supertype "A" | ||
|
||
[case testOverloadedOperatorMethodOverrideWithSwitchedItemOrder] | ||
from foo import * | ||
[file foo.pyi] | ||
from typing import overload, Any | ||
class A: | ||
@overload | ||
def __add__(self, x: 'B') -> 'B': pass | ||
@overload | ||
def __add__(self, x: 'A') -> 'A': pass | ||
class B(A): | ||
@overload | ||
def __add__(self, x: 'A') -> 'A': pass | ||
@overload | ||
def __add__(self, x: 'B') -> 'B': pass | ||
[out] | ||
tmp/foo.pyi:8: error: Signature of "__add__" incompatible with supertype "A" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why have you removed this test? Does it fail? The semantics of overload is not 100% fixed by PEP 484, see python/typing#253, but IIUC the consensus is that order of overloads does matter, so that in this case the override is indeed incompatible. @JukkaL could you please clarify this? |
||
|
||
[case testReverseOperatorMethodArgumentType] | ||
from typing import Any | ||
class A: pass | ||
|
@@ -2494,6 +2477,33 @@ reveal_type(f(BChild())) # E: Revealed type is 'foo.B' | |
[builtins fixtures/classmethod.pyi] | ||
[out] | ||
|
||
[case testSubtypeWithMoreOverloadsThanSupertypeSucceeds] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's have some tests of nasty complicated overloads involving subtyping.
class Super:
@overload
def foo(a: int) -> float: ...
@overload
def foo(a: float) -> Number: ...
@overload
def foo(a: str) -> str: ...
class Sub(Super):
@overload
def foo(a: Number) -> float: ...
@overload
def foo(a: str) -> str: ...
class Super:
@overload
def foo(a: Number) -> Number: ...
@overload
def foo(a: str) -> str: ...
class Sub(Super):
@overload
def foo(a: Number) -> Number: ...
@overload
def foo(a: int) -> str: ...
@overload
def foo(a: str) -> str: ... (look at testPartiallyContravariantOverloadSignatures, for another reference) There's probably even more complexity to this. There usually is. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @sixolet FWIW my goal with this PR wasn't necessarily to 100% make this work perfectly, but it was more to allow a bit more than was originally allowed (without breaking anything, of course!). |
||
from foo import * | ||
[file foo.pyi] | ||
from typing import overload | ||
|
||
|
||
class X: pass | ||
class Y: pass | ||
class Z: pass | ||
|
||
|
||
class A: | ||
@overload | ||
def f(self, x: X) -> X: pass | ||
@overload | ||
def f(self, y: Y) -> Y: pass | ||
|
||
class B(A): | ||
@overload | ||
def f(self, x: X) -> X: pass | ||
@overload | ||
def f(self, y: Y) -> Y: pass | ||
@overload | ||
def f(self, z: Z) -> Z: pass | ||
[builtins fixtures/classmethod.pyi] | ||
[out] | ||
|
||
[case testTypeTypeOverlapsWithObjectAndType] | ||
from foo import * | ||
[file foo.pyi] | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the logic is reversed here. It should be like this: for every item on the right (supertype) there must be an item on the left that is its subtype.