Skip to content

Commit 05521e4

Browse files
pkchgvanrossum
authored andcommitted
Add line # of previous definition (#3396)
*Partial* fix for #1874 - just improve the error message. The duplicate definitions in different if/else branches are still not allowed.
1 parent 266a63f commit 05521e4

File tree

5 files changed

+17
-12
lines changed

5 files changed

+17
-12
lines changed

mypy/semanal.py

+8-3
Original file line numberDiff line numberDiff line change
@@ -3315,7 +3315,7 @@ def check_no_global(self, n: str, ctx: Context,
33153315
elif prev_is_overloaded:
33163316
self.fail("Definition of '{}' missing 'overload'".format(n), ctx)
33173317
else:
3318-
self.name_already_defined(n, ctx)
3318+
self.name_already_defined(n, ctx, self.globals[n])
33193319

33203320
def name_not_defined(self, name: str, ctx: Context) -> None:
33213321
message = "Name '{}' is not defined".format(name)
@@ -3324,8 +3324,13 @@ def name_not_defined(self, name: str, ctx: Context) -> None:
33243324
message += ' {}'.format(extra)
33253325
self.fail(message, ctx)
33263326

3327-
def name_already_defined(self, name: str, ctx: Context) -> None:
3328-
self.fail("Name '{}' already defined".format(name), ctx)
3327+
def name_already_defined(self, name: str, ctx: Context,
3328+
original_ctx: Optional[SymbolTableNode] = None) -> None:
3329+
if original_ctx:
3330+
extra_msg = ' on line {}'.format(original_ctx.node.get_line())
3331+
else:
3332+
extra_msg = ''
3333+
self.fail("Name '{}' already defined{}".format(name, extra_msg), ctx)
33293334

33303335
def fail(self, msg: str, ctx: Context, serious: bool = False, *,
33313336
blocker: bool = False) -> None:

test-data/unit/check-classes.test

+1-1
Original file line numberDiff line numberDiff line change
@@ -714,7 +714,7 @@ A()
714714
class A: pass
715715
class A: pass
716716
[out]
717-
main:4: error: Name 'A' already defined
717+
main:4: error: Name 'A' already defined on line 3
718718

719719
[case testDocstringInClass]
720720
import typing

test-data/unit/check-functions.test

+2-2
Original file line numberDiff line numberDiff line change
@@ -1212,7 +1212,7 @@ from typing import Any
12121212
x = None # type: Any
12131213
if x:
12141214
def f(): pass
1215-
def f(): pass # E: Name 'f' already defined
1215+
def f(): pass # E: Name 'f' already defined on line 4
12161216

12171217
[case testIncompatibleConditionalFunctionDefinition]
12181218
from typing import Any
@@ -1835,7 +1835,7 @@ f = g # E: Incompatible types in assignment (expression has type Callable[[Any,
18351835

18361836
[case testRedefineFunction2]
18371837
def f() -> None: pass
1838-
def f() -> None: pass # E: Name 'f' already defined
1838+
def f() -> None: pass # E: Name 'f' already defined on line 1
18391839

18401840

18411841
-- Special cases

test-data/unit/check-overloading.test

+1-1
Original file line numberDiff line numberDiff line change
@@ -1106,7 +1106,7 @@ def f(a: int) -> None: pass
11061106
def f(a: str) -> None: pass
11071107
[out]
11081108
tmp/foo.pyi:2: error: Single overload definition, multiple required
1109-
tmp/foo.pyi:5: error: Name 'f' already defined
1109+
tmp/foo.pyi:5: error: Name 'f' already defined on line 2
11101110

11111111
[case testOverloadTuple]
11121112
from foo import *

test-data/unit/semanal-errors.test

+5-5
Original file line numberDiff line numberDiff line change
@@ -165,16 +165,16 @@ import typing
165165
class A: pass
166166
class A: pass
167167
[out]
168-
main:3: error: Name 'A' already defined
168+
main:3: error: Name 'A' already defined on line 2
169169

170170
[case testMultipleMixedDefinitions]
171171
import typing
172172
x = 1
173173
def x(): pass
174174
class x: pass
175175
[out]
176-
main:3: error: Name 'x' already defined
177-
main:4: error: Name 'x' already defined
176+
main:3: error: Name 'x' already defined on line 2
177+
main:4: error: Name 'x' already defined on line 2
178178

179179
[case testNameNotImported]
180180
import typing
@@ -1037,13 +1037,13 @@ t = 1 # E: Invalid assignment target
10371037
[case testRedefineTypevar2]
10381038
from typing import TypeVar
10391039
t = TypeVar('t')
1040-
def t(): pass # E: Name 't' already defined
1040+
def t(): pass # E: Name 't' already defined on line 2
10411041
[out]
10421042

10431043
[case testRedefineTypevar3]
10441044
from typing import TypeVar
10451045
t = TypeVar('t')
1046-
class t: pass # E: Name 't' already defined
1046+
class t: pass # E: Name 't' already defined on line 2
10471047
[out]
10481048

10491049
[case testRedefineTypevar4]

0 commit comments

Comments
 (0)