rules_python icon indicating copy to clipboard operation
rules_python copied to clipboard

gazelle_python.yaml can only use one pip_repository

Open alexeagle opened this issue 1 year ago • 3 comments

The modules_mapping rule accepts a list of wheels, but then the manifest generator assumes that all those modules come from a single pip.parse call.

Since many Python projects separate dependencies, i.e. https://pip-tools.readthedocs.io/en/stable/#workflow-for-layered-requirements it's often the case that some users have different requirements repositories, even for the same folder.

For example, in https://github.com/alexeagle/bazel_python_repro/blob/18f4504adcdef9187f68397ea20a4f6672badcc2/app/BUILD.bazel gazelle has generated line 28 as @pip//python_dotenv. However that wheel came from test.in installed at pip.test - so it should have generated @pip.test//python_dotenv. Of course since the wheels were combined in the modules_mapping this information is lost and the gazelle_python.yaml can't indicate which repo should be used for a given import (no matter what folder the gazelle_python.yaml were to appear in)

alexeagle avatar Jun 14 '24 22:06 alexeagle

Note that this is probably low severity, since the workaround is simply to combine the requirements with something like all.in containing

-r test.in
-r runtime.txt

and then when you pip-compile that thing, you get all loads from one external repository, while preserving the multiple requirements input files.

alexeagle avatar Jun 14 '24 22:06 alexeagle

Thanks for noticing this and creating the issue.

I'd just like to note that the proposed workaround defeats the purpose of having separate requirements (for different "projects" in a monorepo): supporting conflicting requirements for different parts of a project. Combining requirements lockfiles is close to impossible because you're pretty much guaranteed to have conflicting requirements, and combining requirements.in may lead to differences in package versions gazelle uses and your code uses.

The workaround is good enough for my small use case but definitely feels clunky.

tboser avatar Jun 22 '24 18:06 tboser

I also hit an issue of conflicting deps. Adding features to gazelle to use different repo mappings in difference cases sounds nontrivial to me. I side stepped this issue by:

  1. Isolating this smallest subset of packages with conflicting deps (for example foobaz)
  2. setting up a tiny requirements_foobaz.in file (with just the one package that conflicted for me)
  3. building a separate pip.parse repo thing for it, called @pip_foobaz
  4. adding a # gazelle:resolve py foobaz @pip_foobaz//foobaz directive for that one dep.

mattlgy avatar Jun 24 '24 13:06 mattlgy