-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
Ensures overloads are ordered from narrow to broad #2138
Conversation
This commit reorders any overloads where the first overload was "shadowing" the second, preventing it from ever being matched by type checkers that work by selecting the first matching overload alternative. For example, the first overload alternative below is strictly broader then the second, preventing it from ever being selected: class Parent: pass class Child(Parent): pass @overload def foo(x: *int) -> Parent: ... @overload def foo(x: int, y: int) -> Child: ... The correct thing to do is to either delete the second overload or rearrange them to look like this: @overload def foo(x: int, y: int) -> Child: ... @overload def foo(x: *int) -> Parent: ... Rationale: I'm currently [working on a proposal][0] that would amend PEP 484 to (a) mandate type checkers check overloads in order and (b) prohibit overloads where an earlier alternative completely shadows a later one. [0]: python/typing#253 (comment) This would prohibit overloads that look like the example below, where the first alternative completely shadows the second. I figured it would be a good idea to make these changes ahead of time: if my proposal is accepted, it'd make the transition smoother. If not, this is hopefully a relatively harmless change. Note: I think some of these overloads could be simplified (e.g. `reversed(...)`), but I mostly stuck with rearranging them in case I was wrong. The only overload I actually changed was `hmac.compare_digest` -- I believe the Python 2 version actually accepts unicode.
I assume you mean "overloads", not "commits" :) |
stdlib/2/os/__init__.pyi
Outdated
def stat_float_times() -> bool: ... | ||
@overload | ||
def stat_float_times(newvalue: bool = ...) -> None: ... |
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.
Shouldn't we just remove the = ...
here?
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.
Done.
lol, good point -- fixed the title |
This pull request relaxes the overlapping overload checks so that if the parameter types of an alternative are a proper subtype of another, the return type needs to only be a regular subtype, not a proper subtype. The net effect is that the return type of the first alternative is allowed to be 'Any'. This *does* make overloads slightly less safe, but 'Any' was always meant to be an escape hatch, so I'm figuring this is fine. **Rationale**: My [proposed changes on overhauling overloads][0] require a few changes to typeshed -- [relevant pull request here][1]. Rather then trying to change both at the same time, I want to get typeshed working first. This was pretty easy to do, apart from the attrs stubs. The issue basically boils down to this: # Alternative 1 @overload def attrib(x: Optional[T]) -> T: ... # Alternative 2 @overload def attrib(x: None = None) -> Any: ... This code typechecks under the current system because alternative 1 completely shadows alternative 2. It fails to typecheck under the new system for the exact same reason. If we swap the two alternatives, it fails under the current system because 'Any' is not a proper subtype of 'T'. It *is*, however, regular subtype of 'T' -- hence this change. [0]: python/typing#253 (comment) [1]: python/typeshed#2138
I reverted the changes to the attrs stubs for now -- it looks like the attrs stubs are currently impossible to type in a way that's compatible with both the current and proposed overload semantics. I submitted a pull request to slightly relax mypy's current overload semantics so that this change can go through. Once my other pull request is accepted, I'll unrevert my revert (unless you decide to accept this pull request as-is -- if so, I can just make another pull request for attrs). |
…5064) This pull request relaxes the overlapping overload checks so that if the parameter types of an alternative are a proper subtype of another, the return type needs to only be a regular subtype, not a proper subtype. The net effect is that the return type of the first alternative is allowed to be 'Any'. This *does* make overloads slightly less safe, but 'Any' was always meant to be an escape hatch, so I'm figuring this is fine. **Rationale**: My [proposed changes on overhauling overloads][0] require a few changes to typeshed -- [relevant pull request here][1]. Rather then trying to change both at the same time, I want to get typeshed working first. This was pretty easy to do, apart from the attrs stubs. The issue basically boils down to this: # Alternative 1 @overload def attrib(x: Optional[T]) -> T: ... # Alternative 2 @overload def attrib(x: None = None) -> Any: ... This code typechecks under the current system because alternative 1 completely shadows alternative 2. It fails to typecheck under the new system for the exact same reason. If we swap the two alternatives, it fails under the current system because 'Any' is not a proper subtype of 'T'. It *is*, however, regular subtype of 'T' -- hence this change. [0]: python/typing#253 (comment) [1]: python/typeshed#2138
@JelleZijlstra -- Ok, looks like third time was the charm. I think this is ready for a second look whenever you have time. |
Syncs typeshed, mostly to pull in some [tweaks I made][0] that makes typeshed compatible with both the current and [proposed][1] overload semantics. [0]: python/typeshed#2138 [1]: python/typing#253 (comment)
Syncs typeshed, mostly to pull in some [tweaks I made][0] that makes typeshed compatible with both the current and [proposed][1] overload semantics. [0]: python/typeshed#2138 [1]: python/typing#253 (comment)
Basically, the same thing as [my previous pull request][0], except the fixes are now focusing on functions with overlapping argument counts. [0]: python#2138
Basically, the same thing as [my previous pull request][0], except the fixes are now focusing on functions with overlapping argument counts. [0]: #2138
This commit reorders any overloads where the first overload was "shadowing" the second, preventing it from ever being matched by type checkers that work by selecting the first matching overload alternative. For example, the first overload alternative below is strictly broader then the second, preventing it from ever being selected: class Parent: pass class Child(Parent): pass @overload def foo(x: *int) -> Parent: ... @overload def foo(x: int, y: int) -> Child: ... The correct thing to do is to either delete the second overload or rearrange them to look like this: @overload def foo(x: int, y: int) -> Child: ... @overload def foo(x: *int) -> Parent: ... Rationale: I'm currently [working on a proposal][0] that would amend PEP 484 to (a) mandate type checkers check overloads in order and (b) prohibit overloads where an earlier alternative completely shadows a later one. [0]: python/typing#253 (comment) This would prohibit overloads that look like the example below, where the first alternative completely shadows the second. I figured it would be a good idea to make these changes ahead of time: if my proposal is accepted, it'd make the transition smoother. If not, this is hopefully a relatively harmless change. Note: I think some of these overloads could be simplified (e.g. `reversed(...)`), but I mostly stuck with rearranging them in case I was wrong. The only overload I actually changed was `hmac.compare_digest` -- I believe the Python 2 version actually accepts unicode.
Basically, the same thing as [my previous pull request][0], except the fixes are now focusing on functions with overlapping argument counts. [0]: python#2138
This commit reorders any overloads where the first overload was "shadowing" the second, preventing it from ever being matched by type checkers that work by selecting the first matching overload alternative. For example, the first overload alternative below is strictly broader then the second, preventing it from ever being selected: class Parent: pass class Child(Parent): pass @overload def foo(x: *int) -> Parent: ... @overload def foo(x: int, y: int) -> Child: ... The correct thing to do is to either delete the second overload or rearrange them to look like this: @overload def foo(x: int, y: int) -> Child: ... @overload def foo(x: *int) -> Parent: ... Rationale: I'm currently [working on a proposal][0] that would amend PEP 484 to (a) mandate type checkers check overloads in order and (b) prohibit overloads where an earlier alternative completely shadows a later one. [0]: python/typing#253 (comment) This would prohibit overloads that look like the example below, where the first alternative completely shadows the second. I figured it would be a good idea to make these changes ahead of time: if my proposal is accepted, it'd make the transition smoother. If not, this is hopefully a relatively harmless change. Note: I think some of these overloads could be simplified (e.g. `reversed(...)`), but I mostly stuck with rearranging them in case I was wrong. The only overload I actually changed was `hmac.compare_digest` -- I believe the Python 2 version actually accepts unicode.
Basically, the same thing as [my previous pull request][0], except the fixes are now focusing on functions with overlapping argument counts. [0]: python#2138
This commit reorders any overloads where the first overload was "shadowing" the second, preventing it from ever being matched by type checkers that work by selecting the first matching overload alternative.
For example, the first overload alternative below is strictly broader then the second, preventing it from ever being selected:
The correct thing to do is to either delete the second overload or rearrange them to look like this:
Rationale: I'm currently working on a proposal that would amend PEP 484 to (a) mandate type checkers check overloads in order and (b) prohibit overloads where an earlier alternative completely shadows a later one.
This would prohibit overloads that look like the example below, where the first alternative completely shadows the second.
I figured it would be a good idea to make these changes ahead of time: if my proposal is accepted, it'd make the transition smoother. If not, this is hopefully a relatively harmless change.
Note: I think some of these overloads could be simplified (e.g.
reversed(...)
), but I mostly stuck with rearranging them in case I was wrong. The only overload I actually changed washmac.compare_digest
-- I believe the Python 2 version actually accepts unicode.