Skip to content

Commit 08e6ba8

Browse files
authored
refactor: add contextmanager to VariableRenameVisitor (#10685)
1 parent 1573336 commit 08e6ba8

File tree

1 file changed

+52
-58
lines changed

1 file changed

+52
-58
lines changed

mypy/renaming.py

Lines changed: 52 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
from typing import Dict, List
1+
from contextlib import contextmanager
2+
from typing import Dict, Iterator, List
23
from typing_extensions import Final
34

45
from mypy.nodes import (
@@ -74,61 +75,47 @@ def visit_mypy_file(self, file_node: MypyFile) -> None:
7475
This is the main entry point to this class.
7576
"""
7677
self.clear()
77-
self.enter_scope(FILE)
78-
self.enter_block()
79-
80-
for d in file_node.defs:
81-
d.accept(self)
82-
83-
self.leave_block()
84-
self.leave_scope()
78+
with self.enter_scope(FILE), self.enter_block():
79+
for d in file_node.defs:
80+
d.accept(self)
8581

8682
def visit_func_def(self, fdef: FuncDef) -> None:
8783
# Conservatively do not allow variable defined before a function to
8884
# be redefined later, since function could refer to either definition.
8985
self.reject_redefinition_of_vars_in_scope()
9086

91-
self.enter_scope(FUNCTION)
92-
self.enter_block()
93-
94-
for arg in fdef.arguments:
95-
name = arg.variable.name
96-
# 'self' can't be redefined since it's special as it allows definition of
97-
# attributes. 'cls' can't be used to define attributes so we can ignore it.
98-
can_be_redefined = name != 'self' # TODO: Proper check
99-
self.record_assignment(arg.variable.name, can_be_redefined)
100-
self.handle_arg(name)
87+
with self.enter_scope(FUNCTION), self.enter_block():
88+
for arg in fdef.arguments:
89+
name = arg.variable.name
90+
# 'self' can't be redefined since it's special as it allows definition of
91+
# attributes. 'cls' can't be used to define attributes so we can ignore it.
92+
can_be_redefined = name != 'self' # TODO: Proper check
93+
self.record_assignment(arg.variable.name, can_be_redefined)
94+
self.handle_arg(name)
10195

102-
for stmt in fdef.body.body:
103-
stmt.accept(self)
104-
105-
self.leave_block()
106-
self.leave_scope()
96+
for stmt in fdef.body.body:
97+
stmt.accept(self)
10798

10899
def visit_class_def(self, cdef: ClassDef) -> None:
109100
self.reject_redefinition_of_vars_in_scope()
110-
self.enter_scope(CLASS)
111-
super().visit_class_def(cdef)
112-
self.leave_scope()
101+
with self.enter_scope(CLASS):
102+
super().visit_class_def(cdef)
113103

114104
def visit_block(self, block: Block) -> None:
115-
self.enter_block()
116-
super().visit_block(block)
117-
self.leave_block()
105+
with self.enter_block():
106+
super().visit_block(block)
118107

119108
def visit_while_stmt(self, stmt: WhileStmt) -> None:
120-
self.enter_loop()
121-
super().visit_while_stmt(stmt)
122-
self.leave_loop()
109+
with self.enter_loop():
110+
super().visit_while_stmt(stmt)
123111

124112
def visit_for_stmt(self, stmt: ForStmt) -> None:
125113
stmt.expr.accept(self)
126114
self.analyze_lvalue(stmt.index, True)
127115
# Also analyze as non-lvalue so that every for loop index variable is assumed to be read.
128116
stmt.index.accept(self)
129-
self.enter_loop()
130-
stmt.body.accept(self)
131-
self.leave_loop()
117+
with self.enter_loop():
118+
stmt.body.accept(self)
132119
if stmt.else_body:
133120
stmt.else_body.accept(self)
134121

@@ -142,9 +129,8 @@ def visit_try_stmt(self, stmt: TryStmt) -> None:
142129
# Variables defined by a try statement get special treatment in the
143130
# type checker which allows them to be always redefined, so no need to
144131
# do renaming here.
145-
self.enter_try()
146-
super().visit_try_stmt(stmt)
147-
self.leave_try()
132+
with self.enter_try():
133+
super().visit_try_stmt(stmt)
148134

149135
def visit_with_stmt(self, stmt: WithStmt) -> None:
150136
for expr in stmt.expr:
@@ -275,40 +261,48 @@ def clear(self) -> None:
275261
self.blocks = []
276262
self.var_blocks = []
277263

278-
def enter_block(self) -> None:
264+
@contextmanager
265+
def enter_block(self) -> Iterator[None]:
279266
self.block_id += 1
280267
self.blocks.append(self.block_id)
281268
self.block_loop_depth[self.block_id] = self.loop_depth
269+
try:
270+
yield
271+
finally:
272+
self.blocks.pop()
282273

283-
def leave_block(self) -> None:
284-
self.blocks.pop()
285-
286-
def enter_try(self) -> None:
274+
@contextmanager
275+
def enter_try(self) -> Iterator[None]:
287276
self.disallow_redef_depth += 1
277+
try:
278+
yield
279+
finally:
280+
self.disallow_redef_depth -= 1
288281

289-
def leave_try(self) -> None:
290-
self.disallow_redef_depth -= 1
291-
292-
def enter_loop(self) -> None:
282+
@contextmanager
283+
def enter_loop(self) -> Iterator[None]:
293284
self.loop_depth += 1
294-
295-
def leave_loop(self) -> None:
296-
self.loop_depth -= 1
285+
try:
286+
yield
287+
finally:
288+
self.loop_depth -= 1
297289

298290
def current_block(self) -> int:
299291
return self.blocks[-1]
300292

301-
def enter_scope(self, kind: int) -> None:
293+
@contextmanager
294+
def enter_scope(self, kind: int) -> Iterator[None]:
302295
self.var_blocks.append({})
303296
self.refs.append({})
304297
self.num_reads.append({})
305298
self.scope_kinds.append(kind)
306-
307-
def leave_scope(self) -> None:
308-
self.flush_refs()
309-
self.var_blocks.pop()
310-
self.num_reads.pop()
311-
self.scope_kinds.pop()
299+
try:
300+
yield
301+
finally:
302+
self.flush_refs()
303+
self.var_blocks.pop()
304+
self.num_reads.pop()
305+
self.scope_kinds.pop()
312306

313307
def is_nested(self) -> int:
314308
return len(self.var_blocks) > 1

0 commit comments

Comments
 (0)