Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion mypyc/codegen/emitmodule.py
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,10 @@ def compile_ir_to_c(
for source in sources
}

names = NameGenerator([[source.module for source in sources] for sources, _ in groups])
names = NameGenerator(
[[source.module for source in sources] for sources, _ in groups],
separate=compiler_options.separate,
)

# Generate C code for each compilation group. Each group will be
# compiled into a separate extension module.
Expand Down
16 changes: 13 additions & 3 deletions mypyc/namegen.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,30 @@ class NameGenerator:

The generated should be internal to a build and thus the mapping is
arbitrary. Just generating names '1', '2', ... would be correct,
though not very usable.
though not very usable. The generated names may be visible in CPU
profiles and when debugging using native debuggers.
"""

def __init__(self, groups: Iterable[list[str]]) -> None:
def __init__(self, groups: Iterable[list[str]], *, separate: bool = False) -> None:
"""Initialize with a list of modules in each compilation group.

The names of modules are used to shorten names referring to
modules, for convenience. Arbitrary module
names are supported for generated names, but uncompiled modules
will use long names.

If separate is True, assume separate compilation. This implies
that we don't have knowledge of all sources that will be linked
together. In this case we won't trim module prefixes, since we
don't have enough information to determine common module prefixes.
"""
self.module_map: dict[str, str] = {}
for names in groups:
self.module_map.update(make_module_translation_map(names))
if not separate:
self.module_map.update(make_module_translation_map(names))
else:
for name in names:
self.module_map[name] = name + "."
self.translations: dict[tuple[str, str], str] = {}
self.used_names: set[str] = set()

Expand Down
14 changes: 14 additions & 0 deletions mypyc/test/test_namegen.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,17 @@ def test_name_generator(self) -> None:
assert g.private_name("foo", "C_x_y") == "foo___C_x_y"
assert g.private_name("foo", "C_x_y") == "foo___C_x_y"
assert g.private_name("foo", "___") == "foo______3_"

g = NameGenerator([["foo.zar"]])
assert g.private_name("foo.zar", "f") == "f"

def test_name_generator_with_separate(self) -> None:
g = NameGenerator([["foo", "foo.zar"]], separate=True)
assert g.private_name("foo", "f") == "foo___f"
assert g.private_name("foo", "C.x.y") == "foo___C___x___y"
assert g.private_name("foo.zar", "C.x.y") == "foo___zar___C___x___y"
assert g.private_name("foo", "C.x_y") == "foo___C___x_y"
assert g.private_name("foo", "___") == "foo______3_"

g = NameGenerator([["foo.zar"]], separate=True)
assert g.private_name("foo.zar", "f") == "foo___zar___f"