fix(pypi): namespace_pkgs should pass correct arguments (#3026) It seems that the only function that did not have unit tests have bugs and the integration tests did not catch it because we weren't creating namespacepkg `__init__.py` files. This change fixes the bug, adds a unit test for the remaining untested function. Fixes #3023 Co-authored-by: Richard Levasseur <richardlev@gmail.com> (cherry picked from commit 49780276797ecdb22afeda0b8c72a680a3c0b41a)
diff --git a/python/private/pypi/namespace_pkgs.bzl b/python/private/pypi/namespace_pkgs.bzl index bf4689a..be6244e 100644 --- a/python/private/pypi/namespace_pkgs.bzl +++ b/python/private/pypi/namespace_pkgs.bzl
@@ -59,25 +59,32 @@ return sorted([d for d in dirs if d not in ignored]) -def create_inits(**kwargs): +def create_inits(*, srcs, ignored_dirnames = [], root = None, copy_file = copy_file, **kwargs): """Create init files and return the list to be included `py_library` srcs. Args: - **kwargs: passed to {obj}`get_files`. + srcs: {type}`src` a list of files to be passed to {bzl:obj}`py_library` + as `srcs` and `data`. This is usually a result of a {obj}`glob`. + ignored_dirnames: {type}`str` a list of patterns to ignore. + root: {type}`str` the prefix to use as the root. + copy_file: the `copy_file` rule to copy files in build context. + **kwargs: passed to {obj}`copy_file`. Returns: {type}`list[str]` to be included as part of `py_library`. """ - srcs = [] - for out in get_files(**kwargs): + ret = [] + for i, out in enumerate(get_files(srcs = srcs, ignored_dirnames = ignored_dirnames, root = root)): src = "{}/__init__.py".format(out) - srcs.append(srcs) + ret.append(src) copy_file( - name = "_cp_{}_namespace".format(out), + # For the target name, use a number instead of trying to convert an output + # path into a valid label. + name = "_cp_{}_namespace".format(i), src = _TEMPLATE, out = src, **kwargs ) - return srcs + return ret
diff --git a/tests/pypi/namespace_pkgs/namespace_pkgs_tests.bzl b/tests/pypi/namespace_pkgs/namespace_pkgs_tests.bzl index 7ac938f..9c382d0 100644 --- a/tests/pypi/namespace_pkgs/namespace_pkgs_tests.bzl +++ b/tests/pypi/namespace_pkgs/namespace_pkgs_tests.bzl
@@ -1,7 +1,7 @@ "" load("@rules_testing//lib:analysis_test.bzl", "test_suite") -load("//python/private/pypi:namespace_pkgs.bzl", "get_files") # buildifier: disable=bzl-visibility +load("//python/private/pypi:namespace_pkgs.bzl", "create_inits", "get_files") # buildifier: disable=bzl-visibility _tests = [] @@ -160,6 +160,45 @@ _tests.append(test_skips_ignored_directories) +def _test_create_inits(env): + srcs = [ + "nested/root/foo/bar/biz.py", + "nested/root/foo/bee/boo.py", + "nested/root/foo/buu/__init__.py", + "nested/root/foo/buu/bii.py", + ] + copy_file_calls = [] + template = Label("//python/private/pypi:namespace_pkg_tmpl.py") + + got = create_inits( + srcs = srcs, + root = "nested/root", + copy_file = lambda **kwargs: copy_file_calls.append(kwargs), + ) + env.expect.that_collection(got).contains_exactly([ + call["out"] + for call in copy_file_calls + ]) + env.expect.that_collection(copy_file_calls).contains_exactly([ + { + "name": "_cp_0_namespace", + "out": "nested/root/foo/__init__.py", + "src": template, + }, + { + "name": "_cp_1_namespace", + "out": "nested/root/foo/bar/__init__.py", + "src": template, + }, + { + "name": "_cp_2_namespace", + "out": "nested/root/foo/bee/__init__.py", + "src": template, + }, + ]) + +_tests.append(_test_create_inits) + def namespace_pkgs_test_suite(name): test_suite( name = name,