Skip to content

Commit 1e372f4

Browse files
authored
[mypyc] Don't simplify module prefixes if using separate compilation (#19206)
Mypyc shortens module prefixes to generate nicer, shorter C names. However, this assumes that we know all possible module prefixes. When doing separate compilation, we only have access to a subset of possible module prefixes, so there's no good way to shorten module prefixes while keeping names unique.
1 parent 1b4ef34 commit 1e372f4

File tree

3 files changed

+31
-4
lines changed

3 files changed

+31
-4
lines changed

mypyc/codegen/emitmodule.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,10 @@ def compile_ir_to_c(
306306
for source in sources
307307
}
308308

309-
names = NameGenerator([[source.module for source in sources] for sources, _ in groups])
309+
names = NameGenerator(
310+
[[source.module for source in sources] for sources, _ in groups],
311+
separate=compiler_options.separate,
312+
)
310313

311314
# Generate C code for each compilation group. Each group will be
312315
# compiled into a separate extension module.

mypyc/namegen.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,20 +34,30 @@ class NameGenerator:
3434
3535
The generated should be internal to a build and thus the mapping is
3636
arbitrary. Just generating names '1', '2', ... would be correct,
37-
though not very usable.
37+
though not very usable. The generated names may be visible in CPU
38+
profiles and when debugging using native debuggers.
3839
"""
3940

40-
def __init__(self, groups: Iterable[list[str]]) -> None:
41+
def __init__(self, groups: Iterable[list[str]], *, separate: bool = False) -> None:
4142
"""Initialize with a list of modules in each compilation group.
4243
4344
The names of modules are used to shorten names referring to
4445
modules, for convenience. Arbitrary module
4546
names are supported for generated names, but uncompiled modules
4647
will use long names.
48+
49+
If separate is True, assume separate compilation. This implies
50+
that we don't have knowledge of all sources that will be linked
51+
together. In this case we won't trim module prefixes, since we
52+
don't have enough information to determine common module prefixes.
4753
"""
4854
self.module_map: dict[str, str] = {}
4955
for names in groups:
50-
self.module_map.update(make_module_translation_map(names))
56+
if not separate:
57+
self.module_map.update(make_module_translation_map(names))
58+
else:
59+
for name in names:
60+
self.module_map[name] = name + "."
5161
self.translations: dict[tuple[str, str], str] = {}
5262
self.used_names: set[str] = set()
5363

mypyc/test/test_namegen.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,17 @@ def test_name_generator(self) -> None:
5252
assert g.private_name("foo", "C_x_y") == "foo___C_x_y"
5353
assert g.private_name("foo", "C_x_y") == "foo___C_x_y"
5454
assert g.private_name("foo", "___") == "foo______3_"
55+
56+
g = NameGenerator([["foo.zar"]])
57+
assert g.private_name("foo.zar", "f") == "f"
58+
59+
def test_name_generator_with_separate(self) -> None:
60+
g = NameGenerator([["foo", "foo.zar"]], separate=True)
61+
assert g.private_name("foo", "f") == "foo___f"
62+
assert g.private_name("foo", "C.x.y") == "foo___C___x___y"
63+
assert g.private_name("foo.zar", "C.x.y") == "foo___zar___C___x___y"
64+
assert g.private_name("foo", "C.x_y") == "foo___C___x_y"
65+
assert g.private_name("foo", "___") == "foo______3_"
66+
67+
g = NameGenerator([["foo.zar"]], separate=True)
68+
assert g.private_name("foo.zar", "f") == "foo___zar___f"

0 commit comments

Comments
 (0)