Skip to content

Commit 94746d6

Browse files
onlinedilevkivskyi
authored andcommitted
Fix __getattr__ and operators related infinite recursion (#6655)
Fixes #6579.
1 parent bee73a0 commit 94746d6

File tree

3 files changed

+20
-3
lines changed

3 files changed

+20
-3
lines changed

mypy/checkexpr.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -704,8 +704,8 @@ def check_call(self,
704704
elif isinstance(callee, UnionType):
705705
return self.check_union_call(callee, args, arg_kinds, arg_names, context, arg_messages)
706706
elif isinstance(callee, Instance):
707-
call_function = analyze_member_access('__call__', callee, context,
708-
False, False, False, self.msg,
707+
call_function = analyze_member_access('__call__', callee, context, is_lvalue=False,
708+
is_super=False, is_operator=True, msg=self.msg,
709709
original_type=callee, chk=self.chk,
710710
in_literal_context=self.is_literal_context())
711711
callable_name = callee.type.fullname() + ".__call__"

mypy/checkmember.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,8 @@ def analyze_member_var_access(name: str,
332332
return analyze_var(name, v, itype, info, mx, implicit=implicit)
333333
elif isinstance(v, FuncDef):
334334
assert False, "Did not expect a function"
335-
elif not v and name not in ['__getattr__', '__setattr__', '__getattribute__']:
335+
elif (not v and name not in ['__getattr__', '__setattr__', '__getattribute__'] and
336+
not mx.is_operator):
336337
if not mx.is_lvalue:
337338
for method_name in ('__getattribute__', '__getattr__'):
338339
method = info.get_method(method_name)

test-data/unit/check-classes.test

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2494,6 +2494,22 @@ b = a.bar
24942494
[out]
24952495
main:9: error: Incompatible types in assignment (expression has type "A", variable has type "B")
24962496

2497+
[case testGetattrWithGetitem]
2498+
class A:
2499+
def __getattr__(self, x: str) -> 'A':
2500+
return A()
2501+
2502+
a = A()
2503+
a[0] # E: Value of type "A" is not indexable
2504+
2505+
[case testGetattrWithCall]
2506+
class A:
2507+
def __getattr__(self, x: str) -> 'A':
2508+
return A()
2509+
2510+
a = A()
2511+
a.y() # E: "A" not callable
2512+
24972513
[case testNestedGetattr]
24982514
def foo() -> object:
24992515
def __getattr__() -> None: # no error because not in a class

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