Repository navigation
More precise overloads for get/pop methods - #10501
Conversation
These trigger false positives in stubtest.
This comment has been minimized.
This comment has been minimized.
|
I think both subtest errors are false-positives: The Union type is compatible with None, since one of the alternatives is an unconstrained type variable. I'll revert these changes for now. |
This comment has been minimized.
This comment has been minimized.
|
As far as I can tell, almost all diffs in mypy_primer are caused by the TypedDict plug-in not recognizing the new dict.get() method. |
That's still disruptive enough to be blocking, however. Are you able to work on a PR to fix mypy's TypedDict plugin to work with your proposed changes? |
|
Yes, we cannot merge this PR with a big breakage like this. I'm looking into what can be done about it. |
This comment has been minimized.
This comment has been minimized.
|
@AlexWaygood I added a work-around for TypedDict. Now all diffs are one of 1) no actual change 2) an improvement 3) a true positive. The jax error is a bit unfortunate, but they simply need to add type annotations for arguments of If I make a PR for mypy so I don't need a work-around here, how do we coordinate releasing it? I assume I need to make the plug-in work with both versions and then we have to wait for a mypy release? |
|
Haven't looked in-depth yet, but at first glance, this looks pretty promising now — thank you! I'll take a closer look tomorrow. |
|
@AlexWaygood The mypy change is very straightforward, but can you suggest the preferred way of making it? I can make a minimal change that works with both versions of typeshed. This will have a small cosmetic downside (reporting an unnecessary Union type in a error message). Otherwise it will be no worse than the current situation. Then I probably have to wait for a mypy release before we can merge this PR? Alternatively, I can make a change in the typeshed version bundled with mypy. I can make a slightly better change this way. For example, I can override |
|
Diff from mypy_primer, showing the effect of this PR on open source code: pylox (https://github.com/sco1/pylox)
+ pylox/containers/array.py:84: note: def pop(self, Any, Any, /) -> Any
- pylox/containers/array.py:84: note: def [_T] pop(self, Any, Any | _T, /) -> Any | _T
+ pylox/containers/array.py:84: note: def [_T] pop(self, Any, _T, /) -> Any | _T
anyio (https://github.com/agronholm/anyio)
+ src/anyio/streams/memory.py:226: error: Unused "type: ignore" comment [unused-ignore]
+ src/anyio/streams/memory.py:231: error: Unused "type: ignore" comment [unused-ignore]
operator (https://github.com/canonical/operator)
- ops/testing.py:929: error: Argument 2 to "get" of "dict" has incompatible type "None"; expected "dict[str, str] | Mapping[str, str]" [arg-type]
+ ops/testing.py:929: error: Argument 2 to "get" of "dict" has incompatible type "None"; expected "Mapping[str, str]" [arg-type]
- ops/testing.py:2014: note: def [_T] pop(self, int, dict[str, Any] | _T, /) -> dict[str, Any] | _T
+ ops/testing.py:2014: note: def pop(self, int, dict[str, Any], /) -> dict[str, Any]
+ ops/testing.py:2014: note: def [_T] pop(self, int, _T, /) -> dict[str, Any] | _T
ibis (https://github.com/ibis-project/ibis)
- ibis/expr/analysis.py:282: error: Unsupported operand types for + ("list[Expr | None]" and "list[Expr]") [operator]
jax (https://github.com/google/jax)
+ jax/_src/core.py:2986: error: Cannot call function of unknown type [operator]
pyjwt (https://github.com/jpadilla/pyjwt)
+ jwt/api_jwk.py:73: error: Returning Any from function declared to return "str | None" [no-any-return]
+ jwt/api_jwk.py:77: error: Returning Any from function declared to return "str | None" [no-any-return]
+ jwt/api_jwk.py:81: error: Returning Any from function declared to return "str | None" [no-any-return]
speedrun.com_global_scoreboard_webapp (https://github.com/Avasam/speedrun.com_global_scoreboard_webapp)
- backend/services/user_updater_helpers.py:190: error: Incompatible types in assignment (expression has type "list[list[Run]] | list[Run]", variable has type "list[Run]") [assignment]
+ backend/services/user_updater_helpers.py:190: error: Incompatible types in assignment (expression has type "list[list[Run]]", variable has type "list[Run]") [assignment]
- backend/services/user_updater_helpers.py:190: error: Argument 2 to "get" of "dict" has incompatible type "list[<nothing>]"; expected "list[list[Run]] | list[Run]" [arg-type]
- backend/services/user_updater_helpers.py:190: note: "List" is invariant -- see https://mypy.readthedocs.io/en/stable/common_issues.html#variance
- backend/services/user_updater_helpers.py:190: note: Consider using "Sequence" instead, which is covariant
- backend/services/user_updater_helpers.py:196: error: Incompatible types in assignment (expression has type "list[list[Run]] | list[Run]", variable has type "list[Run]") [assignment]
+ backend/services/user_updater_helpers.py:196: error: Incompatible types in assignment (expression has type "list[list[Run]]", variable has type "list[Run]") [assignment]
- backend/services/user_updater_helpers.py:196: error: Argument 2 to "get" of "dict" has incompatible type "list[<nothing>]"; expected "list[list[Run]] | list[Run]" [arg-type]
- backend/services/user_updater_helpers.py:196: note: "List" is invariant -- see https://mypy.readthedocs.io/en/stable/common_issues.html#variance
- backend/services/user_updater_helpers.py:196: note: Consider using "Sequence" instead, which is covariant
steam.py (https://github.com/Gobot1234/steam.py)
- steam/state.py:1433: error: Argument 2 to "pop" of "dict" has incompatible type "None"; expected "Friend | CMsgClientFriendsListFriend" [arg-type]
+ steam/state.py:1433: error: Argument 2 to "pop" of "dict" has incompatible type "None"; expected "CMsgClientFriendsListFriend" [arg-type]
+ steam/ext/commands/utils.py:38: note: def get(self, str, _VT, /) -> _VT
+ steam/ext/commands/utils.py:38: note: @overload
- steam/ext/commands/utils.py:38: note: def [_T] get(self, str, _VT | _T, /) -> _VT | _T
+ steam/ext/commands/utils.py:38: note: def [_T] get(self, str, _T, /) -> _VT | _T
+ steam/ext/commands/utils.py:49: note: def pop(self, str, _VT, /) -> _VT
+ steam/ext/commands/utils.py:49: note: @overload
- steam/ext/commands/utils.py:49: note: def [_T] pop(self, str, _VT | _T, /) -> _VT | _T
+ steam/ext/commands/utils.py:49: note: def [_T] pop(self, str, _T, /) -> _VT | _T
+ steam/ext/commands/utils.py:49: note: def pop(self, str, /, default: _VT) -> _VT
+ steam/ext/commands/utils.py:49: note: @overload
- steam/ext/commands/utils.py:49: note: def [_T] pop(self, str, /, default: _VT | _T) -> _VT | _T
+ steam/ext/commands/utils.py:49: note: def [_T] pop(self, str, /, default: _T) -> _VT | _T
cwltool (https://github.com/common-workflow-language/cwltool)
+ cwltool/job.py: note: In function "_setup":
+ cwltool/job.py:193:21: error: Returning Any from function declared to return "bool" [no-any-return]
|
Mypy_primer analysis
All other things in the mypy_primer output are just error messages changing slightly. |
@eltoder I'm not a mypy maintainer (only a triager), but here's a possible plan of action that I think would work well:
|
|
Thanks! |
Fixes #10293