Skip to content

Commit 59450e8

Browse files
committed
Prohibit assignment to __class__ inside instance methods
Implements a check to disallow assignments to self.__class__, as these can cause unsafe runtime behavior. Includes tests for __class__ and related dunder attributes. Fixes python#7724
1 parent 7a32bc1 commit 59450e8

File tree

2 files changed

+25
-0
lines changed

2 files changed

+25
-0
lines changed

mypy/checker.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8880,6 +8880,9 @@ def visit_assignment_stmt(self, s: AssignmentStmt) -> None:
88808880
self.lvalue = True
88818881
for lv in s.lvalues:
88828882
lv.accept(self)
8883+
if isinstance(lv, MemberExpr):
8884+
if lv.name == '__class__':
8885+
self.fail("Assignment to '__class__' is unsafe and not allowed", lv)
88838886
self.lvalue = False
88848887

88858888
def visit_name_expr(self, e: NameExpr) -> None:
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
[case test_assign_to_dunder_class]
2+
class A:
3+
def foo(self):
4+
self.__class__ = B # E: Assignment to '__class__' is unsafe and not allowed
5+
6+
class B:
7+
pass
8+
9+
[case test_assign_to_other_dunder_attributes]
10+
class C:
11+
def bar(self):
12+
self.__name__ = "NewName" # OK
13+
self.__doc__ = "Test doc" # OK
14+
15+
class D:
16+
pass
17+
18+
[case test_assign_to_regular_attribute]
19+
class E:
20+
x = 1
21+
def baz(self):
22+
self.x = 2 # OK

0 commit comments

Comments
 (0)