Skip to content

Commit b266529

Browse files
committed
Add bucketing test
1 parent b34b1cf commit b266529

2 files changed

Lines changed: 184 additions & 0 deletions

File tree

mypyc/test-data/run-multimodule.test

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,28 @@ root_dir = os.path.dirname(native.__file__)
113113
assert os.path.dirname(native.other_sub.__file__) == os.path.join(root_dir, "other_pkg"), \
114114
native.other_sub.__file__
115115

116+
[case testImportFromBucketingEndToEnd]
117+
# separate: [(["native.py", "other_pkg/__init__.py", "other_pkg/other_sub.py"], "testgroup")]
118+
from other_pkg import other_sub as sub_alias, other_attr as attr_alias, py_sub as py_alias
119+
[file other_pkg/__init__.py]
120+
other_attr = 41
121+
[file other_pkg/other_sub.py]
122+
def func() -> int:
123+
return 10
124+
[file other_pkg/py_sub.py]
125+
def func() -> int:
126+
return 20
127+
[file driver.py]
128+
import importlib
129+
import native
130+
other_sub = importlib.import_module("other_pkg.other_sub")
131+
py_sub = importlib.import_module("other_pkg.py_sub")
132+
assert native.sub_alias is other_sub
133+
assert native.attr_alias == 41
134+
assert native.py_alias is py_sub
135+
assert native.sub_alias.func() == 10
136+
assert native.py_alias.func() == 20
137+
116138
[case testNativeTopLevelModuleFileDir]
117139
# separate: [(["native.py", "other_top.py"], "testgroup")]
118140
import other_top

mypyc/test/test_statement.py

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
from __future__ import annotations
2+
3+
import unittest
4+
5+
from mypy.nodes import Import, MypyFile
6+
from mypy.options import Options
7+
from mypyc.errors import Errors
8+
from mypyc.irbuild.builder import IRBuilder, IRVisitor
9+
from mypyc.irbuild.mapper import Mapper
10+
from mypyc.irbuild.prebuildvisitor import PreBuildVisitor
11+
from mypyc.irbuild.statement import (
12+
IMPORT_NATIVE_ATTR,
13+
IMPORT_NATIVE_SUBMODULE,
14+
IMPORT_NON_NATIVE,
15+
classify_import_from,
16+
group_consecutive,
17+
import_globals_id_and_name,
18+
split_import_group_to_python_and_native,
19+
)
20+
from mypyc.options import CompilerOptions
21+
22+
23+
class DummyVisitor(IRVisitor):
24+
pass
25+
26+
27+
def make_builder(
28+
*,
29+
module_name: str = "pkg.current",
30+
native_modules: set[str] | None = None,
31+
same_group_modules: set[str] | None = None,
32+
graph: set[str] | None = None,
33+
) -> IRBuilder:
34+
native_modules = native_modules or set()
35+
same_group_modules = same_group_modules or set()
36+
group_map: dict[str, str | None] = {module_name: "current-group"}
37+
for module in native_modules:
38+
group_map[module] = "current-group" if module in same_group_modules else "other-group"
39+
40+
errors = Errors(Options())
41+
current_file = MypyFile([], [])
42+
current_file._fullname = module_name
43+
pbv = PreBuildVisitor(errors, current_file, {}, {})
44+
builder = IRBuilder(
45+
module_name,
46+
{},
47+
{name: object() for name in (graph or set())},
48+
errors,
49+
Mapper(group_map),
50+
pbv,
51+
DummyVisitor(),
52+
CompilerOptions(),
53+
{},
54+
)
55+
builder.set_module(module_name, module_name.replace(".", "/") + ".py")
56+
return builder
57+
58+
59+
class TestStatementHelpers(unittest.TestCase):
60+
def test_import_globals_id_and_name_for_plain_import(self) -> None:
61+
assert import_globals_id_and_name("foo.bar", None) == ("foo", "foo")
62+
63+
def test_import_globals_id_and_name_for_import_as(self) -> None:
64+
assert import_globals_id_and_name("foo.bar", "baz") == ("foo.bar", "baz")
65+
66+
def test_split_import_group_to_python_and_native_preserves_runs(self) -> None:
67+
builder = make_builder(
68+
native_modules={"pkg.alpha", "pkg.beta", "pkg.gamma"},
69+
same_group_modules={"pkg.alpha", "pkg.beta", "pkg.gamma"},
70+
)
71+
group = [
72+
Import([("pkg.alpha", None), ("py_mod", None)]),
73+
Import([("pkg.beta", "beta_alias"), ("foreign.mod", None), ("pkg.gamma", None)]),
74+
]
75+
group[0].line = 10
76+
group[1].line = 20
77+
78+
result = split_import_group_to_python_and_native(builder, group)
79+
80+
assert result == [
81+
([("pkg.alpha", None, 10)], True),
82+
([("py_mod", None, 10)], False),
83+
([("pkg.beta", "beta_alias", 20)], True),
84+
([("foreign.mod", None, 20)], False),
85+
([("pkg.gamma", None, 20)], True),
86+
]
87+
88+
def test_group_consecutive_groups_by_kind_and_preserves_aliases(self) -> None:
89+
buckets = group_consecutive(
90+
[
91+
(IMPORT_NATIVE_SUBMODULE, "a", "a"),
92+
(IMPORT_NATIVE_SUBMODULE, "b", "b_alias"),
93+
(IMPORT_NON_NATIVE, "c", "c"),
94+
(IMPORT_NATIVE_ATTR, "d", "d_alias"),
95+
(IMPORT_NATIVE_ATTR, "e", "e"),
96+
]
97+
)
98+
99+
assert [(bucket.kind, bucket.names, bucket.as_names) for bucket in buckets] == [
100+
(IMPORT_NATIVE_SUBMODULE, ["a", "b"], ["a", "b_alias"]),
101+
(IMPORT_NON_NATIVE, ["c"], ["c"]),
102+
(IMPORT_NATIVE_ATTR, ["d", "e"], ["d_alias", "e"]),
103+
]
104+
105+
def test_classify_import_from_groups_consecutive_kinds(self) -> None:
106+
builder = make_builder(
107+
native_modules={"pkg.native_a", "pkg.native_b"},
108+
same_group_modules={"pkg.native_a", "pkg.native_b"},
109+
graph={"pkg.native_a", "pkg.native_b", "pkg.foreign_a", "pkg.foreign_b"},
110+
)
111+
112+
buckets = classify_import_from(
113+
builder,
114+
"pkg",
115+
["native_a", "native_b", "foreign_a", "foreign_b"],
116+
["native_a", "native_b_alias", "foreign_a", "foreign_b_alias"],
117+
parent_is_native=True,
118+
)
119+
120+
assert [(bucket.kind, bucket.names, bucket.as_names) for bucket in buckets] == [
121+
(
122+
IMPORT_NATIVE_SUBMODULE,
123+
["native_a", "native_b"],
124+
["native_a", "native_b_alias"],
125+
),
126+
(
127+
IMPORT_NON_NATIVE,
128+
["foreign_a", "foreign_b"],
129+
["foreign_a", "foreign_b_alias"],
130+
),
131+
]
132+
133+
def test_classify_import_from_treats_missing_name_under_native_parent_as_attr(self) -> None:
134+
builder = make_builder(graph={"pkg.foreign"})
135+
136+
buckets = classify_import_from(
137+
builder,
138+
"pkg",
139+
["attr_name", "foreign"],
140+
["attr_alias", "foreign_alias"],
141+
parent_is_native=True,
142+
)
143+
144+
assert [(bucket.kind, bucket.names, bucket.as_names) for bucket in buckets] == [
145+
(IMPORT_NATIVE_ATTR, ["attr_name"], ["attr_alias"]),
146+
(IMPORT_NON_NATIVE, ["foreign"], ["foreign_alias"]),
147+
]
148+
149+
def test_classify_import_from_without_native_parent_never_uses_native_attr(self) -> None:
150+
builder = make_builder()
151+
152+
buckets = classify_import_from(
153+
builder,
154+
"pkg",
155+
["attr_name"],
156+
["attr_alias"],
157+
parent_is_native=False,
158+
)
159+
160+
assert [(bucket.kind, bucket.names, bucket.as_names) for bucket in buckets] == [
161+
(IMPORT_NON_NATIVE, ["attr_name"], ["attr_alias"])
162+
]

0 commit comments

Comments
 (0)