pantsbuild / pants

The Pants Build System
https://www.pantsbuild.org
Apache License 2.0
3.32k stars 636 forks source link

`pex_binary` `entry_point` is silently ignored if in different resolve #20594

Open jasonwbarnett opened 8 months ago

jasonwbarnett commented 8 months ago

Describe the bug

I was onboarding a monorepo that has 100's of pyproject.toml. I went through the onboarding process with pants tailor :: which generated all of the BUILD files. After which I added pex_binary to one of the BUILD files . Then I enabled [python].enable_resolves and added a couple of new [python.resolves] and updated the BUILD file to use the new one I created. When I ran the generated pex binary I was getting an import error. I attempted to manually add the dependencies at which point pants had a beautiful error message which essentially guided me through adding all of the sub modules to the same resolve. After updating them all and re-running pants package the binary worked as expected. I was then able to remove the explicitly defined dependencies and everything continued to work.

My expectation is that if pants detects a dependency isn't using the same resolve it should warn about this situation.

For more context, this is a full diff of what was required to fix the my issue:

diff --git i/utility/company-devops/company_devops/BUILD.pants w/utility/company-devops/company_devops/BUILD.pants
index db46e8d6c9..fcc078087a 100644
--- i/utility/company-devops/company_devops/BUILD.pants
+++ w/utility/company-devops/company_devops/BUILD.pants
@@ -1 +1 @@
-python_sources()
+python_sources(resolve="company-devops")
diff --git i/utility/company-devops/company_devops/azure_devops/BUILD.pants w/utility/company-devops/company_devops/azure_devops/BUILD.pants
index db46e8d6c9..fcc078087a 100644
--- i/utility/company-devops/company_devops/azure_devops/BUILD.pants
+++ w/utility/company-devops/company_devops/azure_devops/BUILD.pants
@@ -1 +1 @@
-python_sources()
+python_sources(resolve="company-devops")
diff --git i/utility/company-devops/compdev/BUILD.pants w/utility/company-devops/compdev/BUILD.pants
index 0c23d586da..2db6047e1a 100644
--- i/utility/company-devops/compdev/BUILD.pants
+++ w/utility/company-devops/compdev/BUILD.pants
@@ -1,10 +1,11 @@
-python_sources()
+python_sources(resolve="company-devops")

 pex_binary(
     name="pex_binary",
     entry_point="main.py",
+    dependencies=[
+      "utility/company-devops/company_devops",
+      "utility/company-devops/compdev",
+    ],
     resolve="company-devops",
 )
diff --git i/utility/company-devops/compdev/commands/BUILD.pants w/utility/company-devops/compdev/commands/BUILD.pants
index db46e8d6c9..fcc078087a 100644
--- i/utility/company-devops/compdev/commands/BUILD.pants
+++ w/utility/company-devops/compdev/commands/BUILD.pants
@@ -1 +1 @@
-python_sources()
+python_sources(resolve="company-devops")

Pants version 2.19

pants.toml

[GLOBAL]
pants_version = "2.19.0"

backend_packages = [
  "pants.backend.docker",
  "pants.backend.experimental.python.lint.ruff",
  "pants.backend.experimental.tools.yamllint",
  "pants.backend.python",
  "pants.backend.python.lint.black",
  "pants.backend.python.typecheck.mypy",
  "pants.backend.shell.lint.shellcheck",
  "pants.backend.shell.lint.shfmt",
]

[source]
marker_filenames = ["pyproject.toml"]

[python]
interpreter_constraints = ['>=3.9,<3.11']
enable_resolves = true
default_resolve = "python-default"

[python.resolves]
python-default = "python-default.lock"
company-devops = "utility/company-devops/pants.lock"

OS MacOS

Additional info

One more note, before updating the BUILD files with resolve pants dependencies --transitive returned no dependencies.

$ pants dependencies --transitive utility/company-devops/compdev:pex_binary

After making the changes described in the diff above, it now shows the correct dependencies, even with the explicitly defined dependencies was removed.

$ pants dependencies --transitive
utility/company-devops/company_devops/azure_devops/__init__.py
utility/company-devops/company_devops/azure_devops/check_pr_description.py
utility/company-devops/company_devops/azure_devops/delete_offline_agents.py
utility/company-devops/compdev/commands/ado.py
utility/company-devops/compdev/main.py
utility/company-devops/pants.lock:_company-devops_lockfile
utility/company-devops/pyproject.toml:poetry
utility/company-devops:poetry#click
utility/company-devops:poetry#requests
huonw commented 8 months ago

Sorry for the trouble! Reproducer:

cd $(mktemp -d)

cat > pants.toml <<EOF
[GLOBAL]
pants_version = "2.19.0"

backend_packages = ["pants.backend.python"]

[python]
interpreter_constraints = ["==3.*"]
enable_resolves = true
default_resolve = "a"

[python.resolves]
a = "a.lock"
b = "b.lock"
EOF

cat > BUILD <<EOF
python_sources(name="py")

pex_binary(name="pex", entry_point="main.py", resolve="b")

pex_binary(name="pex-explicit-dep", entry_point="main.py", dependencies=[":py"], resolve="b")
EOF

touch main.py

# prepare the resolve
pants generate-lockfiles

# BUG: prints nothing
pants dependencies :pex

# BUG: `ImportError: No module named main`
pants run :pex

# GOOD: `NoCompatibleResolveException` diagnostic
pants run :pex-explicit-dep

Output of bash ./run.sh:

10:00:57.62 [INFO] Initializing scheduler...
10:01:00.00 [INFO] Scheduler initialized.
10:01:00.04 [INFO] Starting: Generate lockfile for b
10:01:00.78 [INFO] Completed: Generate lockfile for b
10:01:00.79 [INFO] Wrote lockfile for the resolve `a` to a.lock
10:01:00.79 [INFO] Wrote lockfile for the resolve `b` to b.lock

Traceback (most recent call last):
  File "/Users/huon/.pyenv/versions/3.7.13/lib/python3.7/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/Users/huon/.pyenv/versions/3.7.13/lib/python3.7/runpy.py", line 85, in _run_code
    exec(code, run_globals)
...
  File "/Users/huon/.pyenv/versions/3.7.13/lib/python3.7/runpy.py", line 136, in _get_module_details
    raise error("No module named %s" % mod_name)
ImportError: No module named main
10:03:03.81 [ERROR] 1 Exception encountered:

Engine traceback:
  in `run` goal

NoCompatibleResolveException: The target //:pex-explicit-dep uses the `resolve` `b`, but some of its dependencies are not compatible with that resolve:

  * //main.py:py (a)

All dependencies must work with the same `resolve`. To fix this, either change the `resolve=` field on those dependencies to `b`, or change the `resolve=` of the target //:pex-explicit-dep. If those dependencies should work with multiple resolves, use the `parametrize` mechanism with the `resolve=` field or manually create multiple targets for the same entity.

For more information, see https://www.pantsbuild.org/v2.19/docs/python-third-party-dependencies#multiple-lockfiles.

Note that there's no errors or warnings from for the :pex, main.py is just silently ignored, resulting in runtime failures. The :pex-explicit-dep version has an explicit diagnostic, which would be great to see for the entry_point version too.

lilatomic commented 8 months ago

I thought that this might have been fixed by https://github.com/pantsbuild/pants/pull/20390 , but it doesn't seem to be. I think the ownership on "main.py" is being ignore and no owners are found since it's not in the resolve, so "main.py" isn't added as a dependency. We then return no owners. We could resolve this by adding a check/warning that some owner was found, probably at this line https://github.com/pantsbuild/pants/commit/13bb69f46b01bd5a28061578834a74d51380538c#diff-4740170d8c26730e2b985731f39b65d20446a0e3ea2def3c82491c3f7c99a17fR306