@@ -62,25 +62,40 @@ LIBRARY_ATTRS = union_attrs(
6262 doc = """
6363Package relative prefix to remove from `srcs` for site-packages layouts.
6464
65+ This attribute is mutually exclusive with the {attr}`imports` attribute.
66+
6567When set, `srcs` are interpreted to have a file layout as if they were installed
6668in site-packages. This attribute specifies the directory within `srcs` to treat
6769as the site-packages root so the correct site-packages relative paths for
6870the files can be computed.
6971
70- For example, given `srcs=["site-packages/foo/bar.py"]`, specifying
71- `site_packages_root="site-packages/" means `foo/bar.py` is the file path
72- under the binary's venv site-packages directory that should be made availble.
73-
7472:::{note}
7573This string is relative to the target's *Bazel package*. e.g. Relative to the
7674directory with the BUILD file that defines the target (the same as how e.g.
7775`srcs`).
7876:::
7977
80- :::{attention}
81- Setting both this an the {attr}`imports` attribute may result in undefined
82- behavior. Both will result in the code being importable, but from different
83- sys.path (and thus `__file__`) entries.
78+ For example, given `srcs=["site-packages/foo/bar.py"]`, specifying
79+ `site_packages_root="site-packages/" means `foo/bar.py` is the file path
80+ under the binary's venv site-packages directory that should be made available.
81+
82+ `__init__.py` files are treated specially to provide basic support for [implicit
83+ namespace packages](
84+ https://packaging.python.org/en/latest/guides/packaging-namespace-packages/#native-namespace-packages).
85+ However, the *content* of the files cannot be taken into account, merely their
86+ presence or absense. Stated another way: [pkgutil-style namespace packages](
87+ https://packaging.python.org/en/latest/guides/packaging-namespace-packages/#pkgutil-style-namespace-packages)
88+ won't be understood as namespace packages; they'll be seen as regular packages. This will
89+ likely lead to conflicts with other targets that contribute to the namespace.
90+
91+ :::{tip}
92+ This attributes populates {obj}`PyInfo.site_packages_symlinks`, which is
93+ a topologically ordered depset. This means dependencies closer and earlier
94+ to a consumer have precedence. See {obj}`PyInfo.site_packages_symlinks` for
95+ more information.
96+ :::
97+
98+ :::{versionadded} VERSION_NEXT_FEATURE
8499:::
85100""" ,
86101 ),
@@ -128,7 +143,18 @@ def py_library_impl(ctx, *, semantics):
128143 runfiles .add (collect_runfiles (ctx ))
129144 runfiles = runfiles .build (ctx )
130145
131- site_packages_symlinks = _get_site_packages_symlinks (ctx )
146+ imports = []
147+ site_packages_symlinks = []
148+ if ctx .attr .imports and ctx .attr .site_packages_root :
149+ fail (("Only one of the `imports` or `site_packages_root` attributes " +
150+ "can be set: site_packages_root={}, imports={}" ).format (
151+ ctx .attr .site_packages_root ,
152+ ctx .attr .imports ,
153+ ))
154+ elif ctx .attr .site_packages_root :
155+ site_packages_symlinks = _get_site_packages_symlinks (ctx )
156+ elif ctx .attr .imports :
157+ imports = collect_imports (ctx , semantics )
132158
133159 cc_info = semantics .get_cc_info_for_library (ctx )
134160 py_info , deps_transitive_sources , builtins_py_info = create_py_info (
@@ -138,7 +164,7 @@ def py_library_impl(ctx, *, semantics):
138164 required_pyc_files = required_pyc_files ,
139165 implicit_pyc_files = implicit_pyc_files ,
140166 implicit_pyc_source_files = implicit_pyc_source_files ,
141- imports = collect_imports ( ctx , semantics ) ,
167+ imports = imports ,
142168 site_packages_symlinks = site_packages_symlinks ,
143169 )
144170
0 commit comments