Hey folks! We are dealing with an interesting beha...
# general
b
Hey folks! We are dealing with an interesting behavior that got me trying to understand how Pants deals with test dependencies at test runtime. What happens in this case: • service resolve: dependency A==1.0.0 • pytest resolve (using the
pytest.install_from_resolve
): dependency A=2.0.0 Which dependency will be picked up during test execution? The one from the original resolve or the one from the pytest resolve?
cc @red-jackal-61350
just found this thread and I'm under the impression that this is a problem that pants cannot solve yet https://pantsbuild.slack.com/archives/C046T6T9U/p1739568199747119
h
I'm not sure what you mean by "solving this"? Pants has to pick one, and if you look here you see that pytest is run in a pex environment that has both underlying pexes on its pex_path, but pytest_pex is first, and so the version in that resolve takes precedence.
b
Thanks for the pointer, @happy-kitchen-89482! 😃 Although this problem seems to be rare because the set of dependencies on pytest resolve is relatively small (first time dealing with this in 3 years), it can lead to inconsistencies between the testing and production environment which we wanted to minimize. I'm under the impression we could solve this by guaranteeing that pytest (and other test dependencies) were part of the resolves for which the tests are being executed with, which aligns with this idea also linked above. There are probably other limitations to this approach that I'm not seeing, so let me know your thoughts on that
Gave a shot on that here to try and get to see if something like this would work, but still trying to figure it out the best way to test it. If this is something you think would make sense, I can proceed with a contribution šŸ™
h
Oh I see, yes, in effect getting rid of the tool resolve and requiring the tool to come from the same lockfile as the code.
That makes the most sense, at the expense of having to add the tools to every resolve
b
yes, that would be the idea! We currently handle globally required deps on a "requirements-base.txt" that is included in all resolves on the repo. We'd define the required deps there and set some kind of
[pytest].install_from_target_resolve = true
setting that enables this behavior of not including the pytest pex.
h
And
requirements-base.txt
contains
pytest
? If so you could create a resolve based off
requirements-base.txt
and install pytest from that?
Or is that missing the point because your conflicting dep
A
cannot be in
requirements-base.txt
?
b
pytest is currently not in the
requirements-base.txt
but it could be. Our current solution to the problem is ensuring that both the pytest resolve and all the other resolves have this same conflicting dep pinned to a specific version. But this is not a very scalable solution, as this pinned version is very restrictive and will likely make other resolves stuck to this version just because one of the other resolves has this requirement. In my understanding its reasonable to think that pytest deps should be part of the resolve dependency resolution. I think this behavior is what we see in other tools (poetry, pdm, uv, etc)
h
Yeah, that would seem to be the only sane way to keep pytest and its deps in sync with other deps
other tools basically require pytest to be in the same venv/resolve/lockfile/similar concept as the production code
b
I opened a draft with what this could look like in practice: https://github.com/pantsbuild/pants/pull/22835 Let me know if you think it would make sense to invest more time on that 😃