From 6a1aac8f83670ee918eb9981e046a8dd554df297 Mon Sep 17 00:00:00 2001 From: Ivan Levkivskyi Date: Sat, 6 Sep 2025 01:17:48 +0100 Subject: [PATCH 1/2] Add line number to function cache --- mypy/nodes.py | 8 ++++++++ test-data/unit/check-incremental.test | 22 ++++++++++++++++++++-- test-data/unit/fine-grained.test | 14 ++++++++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/mypy/nodes.py b/mypy/nodes.py index 9cfc61c80b3e..e597fa3490ef 100644 --- a/mypy/nodes.py +++ b/mypy/nodes.py @@ -989,6 +989,8 @@ def serialize(self) -> JsonDict: ), "deprecated": self.deprecated, "original_first_arg": self.original_first_arg, + "line": self.line, + "column": self.column, } @classmethod @@ -1018,6 +1020,8 @@ def deserialize(cls, data: JsonDict) -> FuncDef: else None ) ret.deprecated = data["deprecated"] + ret.line = data["line"] + ret.column = data["column"] # Leave these uninitialized so that future uses will trigger an error del ret.arguments del ret.max_pos @@ -1040,6 +1044,8 @@ def write(self, data: Buffer) -> None: self.dataclass_transform_spec.write(data) write_str_opt(data, self.deprecated) write_str_opt(data, self.original_first_arg) + write_int(data, self.line) + write_int(data, self.column) @classmethod def read(cls, data: Buffer) -> FuncDef: @@ -1058,6 +1064,8 @@ def read(cls, data: Buffer) -> FuncDef: ret.dataclass_transform_spec = DataclassTransformSpec.read(data) ret.deprecated = read_str_opt(data) ret.original_first_arg = read_str_opt(data) + ret.line = read_int(data) + ret.column = read_int(data) # Leave these uninitialized so that future uses will trigger an error del ret.arguments del ret.max_pos diff --git a/test-data/unit/check-incremental.test b/test-data/unit/check-incremental.test index defe7402730f..241ffbd5e139 100644 --- a/test-data/unit/check-incremental.test +++ b/test-data/unit/check-incremental.test @@ -210,6 +210,7 @@ def foo() -> int: [out2] tmp/mod2.py:4: error: Incompatible return value type (got "str", expected "int") +-- Function line numbers can affect error messages, so should be part of public interface. [case testIncrementalInternalScramble] import mod1 @@ -236,8 +237,8 @@ def bar() -> int: def baz() -> int: return 42 -[rechecked mod2] -[stale] +[rechecked mod1, mod2] +[stale mod2] [case testIncrementalMethodInterfaceChange] import mod1 @@ -6897,3 +6898,20 @@ import does_not_exist [builtins fixtures/ops.pyi] [out] [out2] + +[case testCachedUnexpectedKeywordArgument] +import a +[file a.py] +import b +b.lol(uhhhh=12) # tweak +[file a.py.2] +import b +b.lol(uhhhh=12) +[file b.py] +def lol() -> None: pass +[out] +tmp/a.py:2: error: Unexpected keyword argument "uhhhh" for "lol" +tmp/b.py:1: note: "lol" defined here +[out2] +tmp/a.py:2: error: Unexpected keyword argument "uhhhh" for "lol" +tmp/b.py:1: note: "lol" defined here diff --git a/test-data/unit/fine-grained.test b/test-data/unit/fine-grained.test index 888b7bc7e97f..693c7b8cbf3a 100644 --- a/test-data/unit/fine-grained.test +++ b/test-data/unit/fine-grained.test @@ -5178,6 +5178,20 @@ def g(y: T) -> T: a.py:2: error: Unexpected keyword argument "x" c.py:4: note: Called function defined here +[case testFineGrainedUnexpectedKeywordArgument] +import a +[file a.py] +import b +[file a.py.2] +import b +b.lol(uhhhh=12) +[file b.py] +def lol() -> None: pass +[out] +== +a.py:2: error: Unexpected keyword argument "uhhhh" for "lol" +b.py:1: note: "lol" defined here + [case testGenericFineCallableInBound] import a [file a.py] From cadf7ff60b6a79410789760ec136534a4031785b Mon Sep 17 00:00:00 2001 From: Ivan Levkivskyi Date: Sat, 6 Sep 2025 01:41:09 +0100 Subject: [PATCH 2/2] Update couple more tests --- test-data/unit/check-serialize.test | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test-data/unit/check-serialize.test b/test-data/unit/check-serialize.test index 03c185a5694b..eda8f7a5d893 100644 --- a/test-data/unit/check-serialize.test +++ b/test-data/unit/check-serialize.test @@ -158,7 +158,7 @@ def f(__x: int) -> None: pass [out2] tmp/a.py:3: error: Argument 1 to "f" has incompatible type "str"; expected "int" tmp/a.py:4: error: Unexpected keyword argument "__x" for "f" -tmp/b.py: note: "f" defined here +tmp/b.py:1: note: "f" defined here [case testSerializeArgumentKindsErrors] import a @@ -224,7 +224,7 @@ def f(x: int) -> int: pass [out2] tmp/a.py:2: note: Revealed type is "builtins.str" tmp/a.py:3: error: Unexpected keyword argument "x" for "f" -tmp/b.py: note: "f" defined here +tmp/b.py:4: note: "f" defined here [case testSerializeTypeGuardFunction] import a