You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
mypy 0.730 no longer recognizes x**y literals to be ints #7621
With mypy 0.720 (no matter whether the new or the old semantic analyzer is used), I get:
$ mypy --strict f.py
f.py:3: note: Revealed type is 'builtins.int'
Actual behavior
With mypy 0.730 (Python 3.6.8), I get:
$ mypy --strict f.py
f.py:3: note: Revealed type is 'Any'
f.py:4: error: Returning Any from function declared to return "int"
Notes
The behavior from 0.720 is what I'd expect.
One thing I noticed is that the typeshed indeed declares that __pow__ for two ints returns Any. This makes sense because 2 ** -2 is a float. The only recent change which I can see in the typeshed though is the following:
--- a/stdlib/2and3/builtins.pyi+++ b/stdlib/2and3/builtins.pyi@@ -168,7 +168,7 @@ class int:
def __rtruediv__(self, x: int) -> float: ...
def __rmod__(self, x: int) -> int: ...
def __rdivmod__(self, x: int) -> Tuple[int, int]: ...
- def __pow__(self, x: int) -> Any: ... # Return type can be int or float, depending on x.+ def __pow__(self, __x: int, __modulo: Optional[int] = ...) -> Any: ... # Return type can be int or float, depending on x.
def __rpow__(self, x: int) -> Any: ...
def __and__(self, n: int) -> int: ...
This means that the Any return type has always been there but mypy used to correctly recognize that 2 ** 20 is an int. It's difficult for me to tell whether the behavior in 0.730 is a regression compared to 0.720 or actually the desired behavior – it seems to me that mypy follows the typeshed more precisely here. However, maybe it's worth to handle literals like 2 ** 30 in a way that mypy knows that this is always int?
Investigating some, the issue is that mypy actually does already have a plugin to handle exponentiation by a constant as a special case, but adding a new argument to __pow__ in typeshed broke it. Should be an easy fix.
Activity
msullivan commentedon Oct 4, 2019
Investigating some, the issue is that mypy actually does already have a plugin to handle exponentiation by a constant as a special case, but adding a new argument to
__pow__in typeshed broke it. Should be an easy fix.Fix the int.__pow__ plugin
Fix the int.__pow__ plugin (#7632)