From 857507a5ec724cc04eecd38fe2f6f3813c613abb Mon Sep 17 00:00:00 2001 From: Jukka Lehtosalo Date: Fri, 12 Sep 2025 11:13:54 +0100 Subject: [PATCH 1/2] [mypyc] Fix crash with NewType in incremental builds Fixes https://github.com/mypyc/mypyc/issues/1138. --- mypyc/irbuild/prepare.py | 6 +++++- mypyc/test-data/run-multimodule.test | 28 ++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/mypyc/irbuild/prepare.py b/mypyc/irbuild/prepare.py index 61e3e5b95cf4..271e0b19cbc6 100644 --- a/mypyc/irbuild/prepare.py +++ b/mypyc/irbuild/prepare.py @@ -159,7 +159,11 @@ def load_type_map(mapper: Mapper, modules: list[MypyFile], deser_ctx: DeserMaps) """Populate a Mapper with deserialized IR from a list of modules.""" for module in modules: for node in module.names.values(): - if isinstance(node.node, TypeInfo) and is_from_module(node.node, module): + if ( + isinstance(node.node, TypeInfo) + and is_from_module(node.node, module) + and not node.node.is_newtype + ): ir = deser_ctx.classes[node.node.fullname] mapper.type_to_ir[node.node] = ir mapper.symbol_fullnames.add(node.node.fullname) diff --git a/mypyc/test-data/run-multimodule.test b/mypyc/test-data/run-multimodule.test index 4208af0f04c8..3d17734d4387 100644 --- a/mypyc/test-data/run-multimodule.test +++ b/mypyc/test-data/run-multimodule.test @@ -902,3 +902,31 @@ import native [out2] 0 None + +[case testIncrementalCompilationWithNewType] +import other_a +[file other_a.py] +from other_b import MyInt +[file other_a.py.2] +from other_b import MyInt +i = MyInt(42) + +def f(x: MyInt) -> int: + return x + 1 + +def g(x: int) -> MyInt: + return MyInt(x + 2) + +print(i) +print(f(i)) +print(g(13)) +[file other_b.py] +from typing import NewType +MyInt = NewType("MyInt", int) +[file driver.py] +import native +[out] +[out2] +42 +43 +15 From bfed2928d83edffe104176656648f2238c1c649d Mon Sep 17 00:00:00 2001 From: Jukka Lehtosalo Date: Fri, 12 Sep 2025 11:42:16 +0100 Subject: [PATCH 2/2] Also fix named tuples and typed dicts --- mypyc/irbuild/prepare.py | 2 ++ mypyc/test-data/run-multimodule.test | 26 +++++++++++++++++++++++--- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/mypyc/irbuild/prepare.py b/mypyc/irbuild/prepare.py index 271e0b19cbc6..20f2aeef8e6e 100644 --- a/mypyc/irbuild/prepare.py +++ b/mypyc/irbuild/prepare.py @@ -163,6 +163,8 @@ def load_type_map(mapper: Mapper, modules: list[MypyFile], deser_ctx: DeserMaps) isinstance(node.node, TypeInfo) and is_from_module(node.node, module) and not node.node.is_newtype + and not node.node.is_named_tuple + and node.node.typeddict_type is None ): ir = deser_ctx.classes[node.node.fullname] mapper.type_to_ir[node.node] = ir diff --git a/mypyc/test-data/run-multimodule.test b/mypyc/test-data/run-multimodule.test index 3d17734d4387..9323612cb4fb 100644 --- a/mypyc/test-data/run-multimodule.test +++ b/mypyc/test-data/run-multimodule.test @@ -903,12 +903,12 @@ import native 0 None -[case testIncrementalCompilationWithNewType] +[case testIncrementalCompilationWithNonClassTypeDef] import other_a [file other_a.py] from other_b import MyInt [file other_a.py.2] -from other_b import MyInt +from other_b import MyInt, NT, TD i = MyInt(42) def f(x: MyInt) -> int: @@ -920,13 +920,33 @@ def g(x: int) -> MyInt: print(i) print(f(i)) print(g(13)) + +def make_nt(x: int) -> NT: + return NT(x=MyInt(x)) + +print(make_nt(4)) + +def make_td(x: int) -> TD: + return {"x": MyInt(x)} + +print(make_td(5)) + [file other_b.py] -from typing import NewType +from typing import NewType, NamedTuple, TypedDict +from enum import Enum + MyInt = NewType("MyInt", int) +NT = NamedTuple("NT", [("x", MyInt)]) +TD = TypedDict("TD", {"x": MyInt}) + [file driver.py] import native + +[typing fixtures/typing-full.pyi] [out] [out2] 42 43 15 +NT(x=4) +{'x': 5}