cool-easter-32542
07/02/2025, 3:23 PM$ cat helloworld/initboom/hello.py
print('hello')
$ cat helloworld/initboom/__init__.py
import colors
$ cat helloworld/initboom/BUILD
python_sources(
sources=[*python_sources.sources.default, "!hello.py"],
)
python_sources(
name="hello",
sources=["hello.py"],
overrides={
"hello.py": {"dependencies": ["!./__init__.py"]},
},
)
Demo Commit: cburroughs/example-python@dde22b4
Then Pants will agree that hello.py does not depend on `__init__.py`:
$ pants peek helloworld/initboom/hello.py
[
{
"address": "helloworld/initboom/hello.py:hello",
"target_type": "python_source",
"dependencies": [],
"dependencies_raw": [
"!./__init__.py"
],
"description": null,
"goals": [
"run"
],
"interpreter_constraints": null,
"resolve": null,
"restartable": false,
"run_goal_use_sandbox": null,
"skip_black": false,
"skip_docformatter": false,
"skip_flake8": false,
"skip_isort": false,
"skip_mypy": false,
"source_raw": "hello.py",
"sources": [
"helloworld/initboom/hello.py"
],
"sources_fingerprint": "85cdfddd3b32f75322b7109c802e7b6e57f0d6d1e2bec997f871f1a48ff5fbbb",
"tags": null
}
]
But pants run will than go boom with:
$ pants run helloworld/initboom/hello.py
Traceback (most recent call last):
File "/tmp/pants-sandbox-qLd9dw/./.cache/pex_root/venvs/1/0af9aa852e07539345a74140f1edf47e78828232/108a3ddc84230ab282ea6312e06cb68f51008ce5/pex", line 358, in <module>
boot(
File "/tmp/pants-sandbox-qLd9dw/./.cache/pex_root/venvs/1/0af9aa852e07539345a74140f1edf47e78828232/108a3ddc84230ab282ea6312e06cb68f51008ce5/pex", line 341, in boot
runpy.run_module(module_name, run_name="__main__", alter_sys=True)
File "/usr/lib/python3.9/runpy.py", line 221, in run_module
mod_name, mod_spec, code = _get_module_details(mod_name)
File "/usr/lib/python3.9/runpy.py", line 111, in _get_module_details
__import__(pkg_name)
File "/tmp/pants-sandbox-qLd9dw/./helloworld/initboom/__init__.py", line 1, in <module>
import colors
ModuleNotFoundError: No module named 'colors'
This is due to prepare_python_sources unconditionally adding __init__.py files to the sandbox
pants/src/python/pants/backend/python/util_rules/python_sources.py
Line 108 in</pantsbuild/pants/commit/ffac37328cfa98f2d0fbcd82df9f63e4e0643b90|ffac373>
| missing_init_files = await find_ancestor_files( |
| ----------------------------------------------- |
originally added in #10166
If the exclusion isn't going to work, Pants ought to at least throw a warning/error something.
Pants version
2.26.0
Additional info
Why am I trying to do this crazy thingy? I'm using Pants and Python to dynamically generate CI pipelines in a monorepo. Some process looks for files matching ci_provider_name_pipeline.py, and then imports them. This is nice because I get to generate pipelines in a real programming language instead of yaml glop. But leaves me in a weird state with regards to Pants, I want them to be "regular python modules" for the purposes of linting, type checking, and all those good things, and it is convenient for the pipeline for a project to be co-located, but I don't want the pipelines and the projects themselves to share dependencies. (No using tensorflow in your ci pipeline generator!)
With Pants' file based model, these sorts of exclusions make sense, but they are pretty wacky from a "how are python modules expected to work" perspective. So I'm waffling on if this case should be supported at all, but the silently ignoring exclusions behavior feels like a bug regardless.
(A slightly less wacky variant that I think would run into the same issue is python sources from multiple resolves in the same directory)
pantsbuild/pants