@@ -218,6 +218,7 @@ def _test_optimized_grouping_single_toplevel(name):
218218 empty_files (
219219 name = name + "_files" ,
220220 paths = [
221+ "site-packages/pkg2/__init__.py" ,
221222 "site-packages/pkg2/a.txt" ,
222223 "site-packages/pkg2/b_mod.so" ,
223224 ],
@@ -247,6 +248,7 @@ def _test_optimized_grouping_single_toplevel_impl(env, target):
247248 "pkg2" ,
248249 link_to_path = rr + "pkg2" ,
249250 files = [
251+ "tests/venv_site_packages_libs/app_files_building/site-packages/pkg2/__init__.py" ,
250252 "tests/venv_site_packages_libs/app_files_building/site-packages/pkg2/a.txt" ,
251253 "tests/venv_site_packages_libs/app_files_building/site-packages/pkg2/b_mod.so" ,
252254 ],
@@ -263,6 +265,68 @@ def _test_optimized_grouping_single_toplevel_impl(env, target):
263265 # The point of the optimization is to avoid having to merge conflicts.
264266 env .expect .that_collection (conflicts ).contains_exactly ([])
265267
268+ def _test_optimized_grouping_implicit_namespace_packages (name ):
269+ empty_files (
270+ name = name + "_files" ,
271+ paths = [
272+ "site-packages/namespace/part1/foo.py" ,
273+ "site-packages/namespace/part2/bar.py" ,
274+ "site-packages/namespace-1.0.dist-info/METADATA" ,
275+ ],
276+ )
277+ analysis_test (
278+ name = name ,
279+ impl = _test_optimized_grouping_implicit_namespace_packages_impl ,
280+ target = name + "_files" ,
281+ )
282+
283+ _tests .append (_test_optimized_grouping_implicit_namespace_packages )
284+
285+ def _test_optimized_grouping_implicit_namespace_packages_impl (env , target ):
286+ test_ctx = _ctx (workspace_name = env .ctx .workspace_name )
287+ entries = get_venv_symlinks (
288+ test_ctx ,
289+ target .files .to_list (),
290+ package = "pkg3" ,
291+ version_str = "1.0" ,
292+ site_packages_root = env .ctx .label .package + "/site-packages" ,
293+ )
294+ actual = _venv_symlinks_from_entries (entries )
295+
296+ rr = "{}/{}/site-packages/" .format (test_ctx .workspace_name , env .ctx .label .package )
297+ expected = [
298+ _venv_symlink (
299+ "namespace/part1" ,
300+ link_to_path = rr + "namespace/part1" ,
301+ files = [
302+ "tests/venv_site_packages_libs/app_files_building/site-packages/namespace/part1/foo.py" ,
303+ ],
304+ ),
305+ _venv_symlink (
306+ "namespace/part2" ,
307+ link_to_path = rr + "namespace/part2" ,
308+ files = [
309+ "tests/venv_site_packages_libs/app_files_building/site-packages/namespace/part2/bar.py" ,
310+ ],
311+ ),
312+ _venv_symlink (
313+ "namespace-1.0.dist-info" ,
314+ link_to_path = rr + "namespace-1.0.dist-info" ,
315+ files = [
316+ "tests/venv_site_packages_libs/app_files_building/site-packages/namespace-1.0.dist-info/METADATA" ,
317+ ],
318+ ),
319+ ]
320+ expected = sorted (expected , key = lambda e : (e .link_to_path , e .venv_path ))
321+ env .expect .that_collection (
322+ actual ,
323+ ).contains_exactly (expected )
324+
325+ _ , conflicts = build_link_map (test_ctx , entries , return_conflicts = True )
326+
327+ # The point of the optimization is to avoid having to merge conflicts.
328+ env .expect .that_collection (conflicts ).contains_exactly ([])
329+
266330def _test_package_version_filtering (name ):
267331 analysis_test (
268332 name = name ,
0 commit comments