Skip to content

Commit 89b9154

Browse files
authored
New semantic analyzer: support --allow-redefinition (#6466)
Fixes #6317.
1 parent cec33dc commit 89b9154

File tree

3 files changed

+9
-2
lines changed

3 files changed

+9
-2
lines changed

mypy/build.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
from mypy.fscache import FileSystemCache
6060
from mypy.metastore import MetadataStore, FilesystemMetadataStore, SqliteMetadataStore
6161
from mypy.typestate import TypeState, reset_global_state
62+
from mypy.renaming import VariableRenameVisitor
6263

6364
from mypy.mypyc_hacks import BuildManagerBase
6465

@@ -1916,6 +1917,9 @@ def semantic_analysis_pass1(self) -> None:
19161917
analyzer.visit_file(self.tree, self.xpath, self.id, options)
19171918
# TODO: Do this while contructing the AST?
19181919
self.tree.names = SymbolTable()
1920+
if options.allow_redefinition:
1921+
# Perform renaming across the AST to allow variable redefinitions
1922+
self.tree.accept(VariableRenameVisitor())
19191923
else:
19201924
# Do the first pass of semantic analysis: add top-level
19211925
# definitions in the file to the symbol table. We must do

mypy/newsemanal/semanal.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4180,14 +4180,18 @@ def name_already_defined(self, name: str, ctx: Context,
41804180
# Therefore its line number is always 1, which is not useful for this
41814181
# error message.
41824182
extra_msg = ' (by an import)'
4183-
elif node and node.line != -1 and self.cur_mod_id in split_module_names(node.fullname()):
4183+
elif node and node.line != -1 and self.is_local_name(node.fullname()):
41844184
# TODO: Using previous symbol node may give wrong line. We should use
41854185
# the line number where the binding was established instead.
41864186
extra_msg = ' on line {}'.format(node.line)
41874187
else:
41884188
extra_msg = ' (possibly by an import)'
41894189
self.fail("Name '{}' already defined{}".format(unmangle(name), extra_msg), ctx)
41904190

4191+
def is_local_name(self, name: str) -> bool:
4192+
"""Does name look like reference to a definition in the current module?"""
4193+
return self.cur_mod_id in split_module_names(name) or '.' not in name
4194+
41914195
def fail(self, msg: str, ctx: Context, serious: bool = False, *,
41924196
blocker: bool = False) -> None:
41934197
if (not serious and

mypy/test/hacks.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
'check-overloading.test',
3131
'check-protocols.test',
3232
'check-python2.test',
33-
'check-redefine.test',
3433
'check-semanal-error.test',
3534
'check-serialize.test',
3635
'check-statements.test',

0 commit comments

Comments
 (0)