Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion mypy/checkexpr.py
Original file line number Diff line number Diff line change
Expand Up @@ -4096,7 +4096,7 @@ def lookup_definer(typ: Instance, attr_name: str) -> str | None:
results = []
for name, method, obj, arg in variants:
with self.msg.filter_errors(save_filtered_errors=True) as local_errors:
result = self.check_method_call(op_name, obj, method, [arg], [ARG_POS], context)
result = self.check_method_call(name, obj, method, [arg], [ARG_POS], context)
if local_errors.has_new_errors():
errors.append(local_errors.filtered_errors())
results.append(result)
Expand Down
16 changes: 16 additions & 0 deletions test-data/unit/check-custom-plugin.test
Original file line number Diff line number Diff line change
Expand Up @@ -1110,3 +1110,19 @@ plugins = """
<ROOT>/test-data/unit/plugins/method_in_decorator.py,
"""
[out]



[case magicMethodReverse]
# flags: --config-file tmp/mypy.ini
from typing import Literal

op1: Literal[3] = 3
op2: Literal[4] = 4
c = op1 + op2
reveal_type(c) # N: Revealed type is "Literal[7]"

[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/magic_method.py
[builtins fixtures/ops.pyi]
24 changes: 24 additions & 0 deletions test-data/unit/plugins/magic_method.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from mypy.types import LiteralType, AnyType, TypeOfAny, Type
from mypy.plugin import Plugin, MethodContext
from typing import Callable, Optional

# If radd exists, there shouldn't be an error. If it doesn't exist, then there will be an error
def type_add(ctx: MethodContext) -> Type:
ctx.api.fail("fail", ctx.context)
return AnyType(TypeOfAny.from_error)

def type_radd(ctx: MethodContext) -> Type:
return LiteralType(7, fallback=ctx.api.named_generic_type('builtins.int', []))


class TestPlugin(Plugin):

def get_method_hook(self, fullname: str) -> Optional[Callable[[MethodContext], Type]]:
if fullname == 'builtins.int.__add__':
return type_add
if fullname == 'builtins.int.__radd__':
return type_radd
return None

def plugin(version: str) -> type[TestPlugin]:
return TestPlugin