Skip to content

Commit d7945cc

Browse files
committed
Allow passing in namespace packages to build_graph
This gets us most of the way, but we still want to include the namespace packages in the graph too (depending on what's passed in).
1 parent f035de5 commit d7945cc

File tree

3 files changed

+94
-24
lines changed

3 files changed

+94
-24
lines changed

src/grimp/application/usecases.py

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
from ..application.ports.modulefinder import AbstractModuleFinder, FoundPackage, ModuleFile
1414
from ..application.ports.packagefinder import AbstractPackageFinder
1515
from ..domain.valueobjects import DirectImport, Module
16-
from .. import exceptions
1716
from .config import settings
1817

1918

@@ -84,18 +83,14 @@ def _find_packages(
8483
package_directories = package_finder.determine_package_directories(
8584
package_name=package_name, file_system=file_system
8685
)
87-
try:
88-
[package_directory] = package_directories
89-
except ValueError:
90-
# TODO handle multiple directories.
91-
raise exceptions.NamespacePackageEncountered
92-
93-
found_package = module_finder.find_package(
94-
package_name=package_name,
95-
package_directory=package_directory,
96-
file_system=file_system,
97-
)
98-
found_packages.add(found_package)
86+
for package_directory in package_directories:
87+
found_package = module_finder.find_package(
88+
package_name=package_name,
89+
package_directory=package_directory,
90+
file_system=file_system,
91+
)
92+
found_packages.add(found_package)
93+
9994
return found_packages
10095

10196

tests/functional/test_namespace_packages.py

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import pytest # type: ignore
22

3-
from grimp import build_graph, exceptions
3+
from grimp import build_graph
44

55
"""
66
For ease of reference, these are the imports of all the files:
@@ -17,14 +17,16 @@
1717
nestednamespace.foo.alpha.blue.one, nestednamespace.bar.beta.orange
1818
"""
1919

20+
YELLOW_MODULES = {"mynamespace.yellow"}
21+
GREEN_MODULES = {"mynamespace.green", "mynamespace.green.alpha"}
22+
BLUE_MODULES = {"mynamespace.blue", "mynamespace.blue.alpha", "mynamespace.blue.beta"}
2023

21-
def test_build_graph_for_namespace():
22-
with pytest.raises(exceptions.NamespacePackageEncountered):
23-
build_graph("mynamespace", cache_dir=None)
2424

25+
def test_build_graph_for_namespace():
26+
graph = build_graph("mynamespace", cache_dir=None)
2527

26-
GREEN_MODULES = {"mynamespace.green", "mynamespace.green.alpha"}
27-
BLUE_MODULES = {"mynamespace.blue", "mynamespace.blue.alpha", "mynamespace.blue.beta"}
28+
assert graph.modules == YELLOW_MODULES | GREEN_MODULES | BLUE_MODULES
29+
assert graph.count_imports()
2830

2931

3032
@pytest.mark.parametrize(
@@ -99,14 +101,42 @@ def test_import_between_namespace_children():
99101

100102
# Nested namespaces
101103

104+
FOO_ALPHA_BLUE_MODULES = {
105+
"nestednamespace.foo.alpha.blue",
106+
"nestednamespace.foo.alpha.blue.one",
107+
"nestednamespace.foo.alpha.blue.two",
108+
}
109+
FOO_ALPHA_GREEN_MODULES = {
110+
"nestednamespace.foo.alpha.green",
111+
"nestednamespace.foo.alpha.green.one",
112+
"nestednamespace.foo.alpha.green.two",
113+
}
114+
BAR_BETA_MODULES = {
115+
"nestednamespace.bar.beta",
116+
"nestednamespace.bar.beta.orange",
117+
}
118+
102119

103120
@pytest.mark.parametrize(
104-
"package_name",
105-
("nestednamespace", "nestednamespace.foo", "nestednamespace.foo.alpha"),
121+
"package_name, expected",
122+
[
123+
# TODO: include the namespace packages as modules too.
124+
(
125+
"nestednamespace",
126+
FOO_ALPHA_BLUE_MODULES | FOO_ALPHA_GREEN_MODULES | BAR_BETA_MODULES,
127+
),
128+
(
129+
"nestednamespace.foo",
130+
FOO_ALPHA_BLUE_MODULES | FOO_ALPHA_GREEN_MODULES,
131+
),
132+
("nestednamespace.foo.alpha", FOO_ALPHA_BLUE_MODULES | FOO_ALPHA_GREEN_MODULES),
133+
],
106134
)
107-
def test_build_graph_for_nested_namespace(package_name):
108-
with pytest.raises(exceptions.NamespacePackageEncountered):
109-
build_graph(package_name, cache_dir=None)
135+
def test_build_graph_for_nested_namespace(package_name, expected):
136+
graph = build_graph(package_name, cache_dir=None)
137+
138+
assert graph.modules == expected
139+
assert graph.count_imports()
110140

111141

112142
@pytest.mark.parametrize(

tests/unit/application/test_usecases.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,3 +163,48 @@ class FakePackageFinder(BaseFakePackageFinder):
163163
"mypackage.foo.one",
164164
}
165165
assert expected_modules == graph.modules
166+
167+
def test_namespace_package_passed_as_root(self):
168+
file_system = FakeFileSystem(
169+
contents="""
170+
/path/to/mypackage/
171+
foo/
172+
__init__.py
173+
one.py
174+
two/
175+
__init__.py
176+
green.py
177+
blue.py
178+
bar/
179+
__init__.py
180+
three.py
181+
/different-path/to/mypackage/
182+
foobar/
183+
__init__.py
184+
four.py
185+
""",
186+
)
187+
188+
class FakePackageFinder(BaseFakePackageFinder):
189+
directory_map = {
190+
"mypackage": {
191+
"/path/to/mypackage",
192+
"/different-path/to/mypackage",
193+
}
194+
}
195+
196+
with override_settings(FILE_SYSTEM=file_system, PACKAGE_FINDER=FakePackageFinder()):
197+
graph = usecases.build_graph("mypackage")
198+
199+
assert graph.modules == {
200+
# TODO "mypackage" should also be included.
201+
"mypackage.foo",
202+
"mypackage.foo.one",
203+
"mypackage.foo.two",
204+
"mypackage.foo.two.green",
205+
"mypackage.foo.two.blue",
206+
"mypackage.bar",
207+
"mypackage.bar.three",
208+
"mypackage.foobar",
209+
"mypackage.foobar.four",
210+
}

0 commit comments

Comments
 (0)