8000 Bug fix of __r<magic_methods>__ being used under the same __<magic_me… · python/mypy@25b1bb8 · GitHub
[go: up one dir, main page]

Skip to content

Commit 25b1bb8

Browse files
authored
Bug fix of __r<magic_methods>__ being used under the same __<magic_method>__ hook (#18995)
Fixes #18945 (This was a feature request that turned out to be a bug) Essentially, I was trying to create a custom plugin and implement __add__. In the process I discovered that __radd__ would implicitly be called if __add__ has an error but it would be called under the same __add__ hook (instead of radd) which is bad for non-commutative operations. This has been fixed. I also added a test for it.
1 parent 51f80f8 commit 25b1bb8

File tree

3 files changed

+41
-1
lines changed

3 files changed

+41
-1
lines changed

mypy/checkexpr.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4096,7 +4096,7 @@ def lookup_definer(typ: Instance, attr_name: str) -> str | None:
40964096
results = []
40974097
for name, method, obj, arg in variants:
40984098
with self.msg.filter_errors(save_filtered_errors=True) as local_errors:
4099-
result = self.check_method_call(op_name, obj, method, [arg], [ARG_POS], context)
4099+
result = self.check_method_call(name, obj, method, [arg], [ARG_POS], context)
41004100
if local_errors.has_new_errors():
41014101
errors.append(local_errors.filtered_errors())
41024102
results.append(result)

test-data/unit/check-custom-plugin.test

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,3 +1110,19 @@ plugins = """
11101110
<ROOT>/test-data/unit/plugins/method_in_decorator.py,
11111111
"""
11121112
[out]
1113+
1114+
1115+
1116+
[case magicMethodReverse]
1117+
# flags: --config-file tmp/mypy.ini
1118+
from typing import Literal
1119+
1120+
op1: Literal[3] = 3
1121+
op2: Literal[4] = 4
1122+
c = op1 + op2
1123+
reveal_type(c) # N: Revealed type is "Literal[7]"
1124+
1125+
[file mypy.ini]
1126+
\[mypy]
1127+
plugins=<ROOT>/test-data/unit/plugins/magic_method.py
1128+
[builtins fixtures/ops.pyi]
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from mypy.types import LiteralType, AnyType, TypeOfAny, Type
2+
from mypy.plugin import Plugin, MethodContext
3+
from typing import Callable, Optional
4+
5+
# If radd exists, there shouldn't be an error. If it doesn't exist, then there will be an error
6+
def type_add(ctx: MethodContext) -> Type:
7+
ctx.api.fail("fail", ctx.context)
8+
return AnyType(TypeOfAny.from_error)
9+
10+
def type_radd(ctx: MethodContext) -> Type:
11+
return LiteralType(7, fallback=ctx.api.named_generic_type('builtins.int', []))
12+
13+
14+
class TestPlugin(Plugin):
15+
16+
def get_method_hook(self, fullname: str) -> Optional[Callable[[MethodContext], Type]]:
17+
if fullname == 'builtins.int.__add__':
18+
return type_add
19+
if fullname == 'builtins.int.__radd__':
20+
return type_radd
21+
return None
22+
23+
def plugin(version: str) -> type[TestPlugin]:
24+
return TestPlugin

0 commit comments

Comments
 (0)
0