Skip to content

Commit 61e08cc

Browse files
authored
Fix the int.__pow__ plugin (python#7632)
A recent typeshed change added a modulo argument to int.__pow__ which broke the plugin. Tested manually. I didn't add a test because to be useful it would need to be a cmdline test (so it uses the real typeshed) and this doesn't seem worth adding a slow cmdline test for. Happy to add it if someone disagrees though. Fixes python#7621.
1 parent 8f381b8 commit 61e08cc

File tree

5 files changed

+27
-23
lines changed

5 files changed

+27
-23
lines changed

mypy/plugins/default.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -365,8 +365,10 @@ def typed_dict_update_signature_callback(ctx: MethodSigContext) -> CallableType:
365365

366366
def int_pow_callback(ctx: MethodContext) -> Type:
367367
"""Infer a more precise return type for int.__pow__."""
368-
if (len(ctx.arg_types) == 1
369-
and len(ctx.arg_types[0]) == 1):
368+
# int.__pow__ has an optional modulo argument,
369+
# so we expect 2 argument positions
370+
if (len(ctx.arg_types) == 2
371+
and len(ctx.arg_types[0]) == 1 and len(ctx.arg_types[1]) == 0):
370372
arg = ctx.args[0][0]
371373
if isinstance(arg, IntExpr):
372374
exponent = arg.value

mypy/test/testcmdline.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ def test_python_cmdline(testcase: DataDrivenTestCase, step: int) -> None:
8989
if obvious_result != result:
9090
out.append('== Return code: {}'.format(result))
9191
expected_out = testcase.output if step == 1 else testcase.output2[step]
92+
# Strip "tmp/" out of the test so that # E: works...
93+
expected_out = [s.replace("tmp" + os.sep, "") for s in expected_out]
9294
assert_string_arrays_equal(expected_out, out,
9395
'Invalid output ({}, line {}){}'.format(
9496
testcase.file, testcase.line,

test-data/unit/check-expressions.test

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2311,25 +2311,6 @@ class B: ...
23112311

23122312
[builtins fixtures/dict.pyi]
23132313

2314-
-- Type checker default plugin
2315-
-- ---------------------------
2316-
2317-
2318-
[case testIntPow]
2319-
a = 1
2320-
b = a + 2
2321-
reveal_type(a**0) # N: Revealed type is 'builtins.int'
2322-
reveal_type(a**1) # N: Revealed type is 'builtins.int'
2323-
reveal_type(a**2) # N: Revealed type is 'builtins.int'
2324-
reveal_type(a**-0) # N: Revealed type is 'builtins.int'
2325-
reveal_type(a**-1) # N: Revealed type is 'builtins.float'
2326-
reveal_type(a**(-2)) # N: Revealed type is 'builtins.float'
2327-
reveal_type(a**b) # N: Revealed type is 'Any'
2328-
reveal_type(a.__pow__(2)) # N: Revealed type is 'builtins.int'
2329-
reveal_type(a.__pow__(a)) # N: Revealed type is 'Any'
2330-
a.__pow__() # E: Too few arguments for "__pow__" of "int"
2331-
[builtins fixtures/ops.pyi]
2332-
23332314
[case testTypeAnnotationNeededMultipleAssignment]
23342315
x, y = [], [] # E: Need type annotation for 'x' (hint: "x: List[<type>] = ...") \
23352316
# E: Need type annotation for 'y' (hint: "y: List[<type>] = ...")

test-data/unit/cmdline.test

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,25 @@ python_version = 3.4
578578
python_version = 3.6
579579
[out]
580580

581+
-- This should be a dumping ground for tests of plugins that are sensitive to
582+
-- typeshed changes.
583+
[case testTypeshedSensitivePlugins]
584+
# cmd: mypy int_pow.py
585+
586+
[file int_pow.py]
587+
a = 1
588+
b = a + 2
589+
reveal_type(a**0) # N: Revealed type is 'builtins.int'
590+
reveal_type(a**1) # N: Revealed type is 'builtins.int'
591+
reveal_type(a**2) # N: Revealed type is 'builtins.int'
592+
reveal_type(a**-0) # N: Revealed type is 'builtins.int'
593+
reveal_type(a**-1) # N: Revealed type is 'builtins.float'
594+
reveal_type(a**(-2)) # N: Revealed type is 'builtins.float'
595+
reveal_type(a**b) # N: Revealed type is 'Any'
596+
reveal_type(a.__pow__(2)) # N: Revealed type is 'builtins.int'
597+
reveal_type(a.__pow__(a)) # N: Revealed type is 'Any'
598+
a.__pow__() # E: Too few arguments for "__pow__" of "int"
599+
581600
[case testDisallowAnyUnimported]
582601
# cmd: mypy main.py
583602
[file mypy.ini]

test-data/unit/fixtures/ops.pyi

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import overload, Any, Generic, Sequence, Tuple, TypeVar
1+
from typing import overload, Any, Generic, Sequence, Tuple, TypeVar, Optional
22

33
Tco = TypeVar('Tco', covariant=True)
44

@@ -46,7 +46,7 @@ class int:
4646
def __rtruediv__(self, x: 'int') -> 'int': pass
4747
def __mod__(self, x: 'int') -> 'int': pass
4848
def __floordiv__(self, x: 'int') -> 'int': pass
49-
def __pow__(self, x: 'int') -> Any: pass
49+
def __pow__(self, x: 'int', __modulo: Optional[int] = ...) -> Any: pass
5050
def __pos__(self) -> 'int': pass
5151
def __neg__(self) -> 'int': pass
5252
def __eq__(self, x: object) -> bool: pass

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy