I have 2 lockfiles/resolves in my project: `python...
# plugins
q
I have 2 lockfiles/resolves in my project:
python-default
which has all the dependencies for my project and
pants-plugins
which has the pants dependencies for my custom pants plugins. When I run
pants check ::
, I get the following output: I don't know why it is checking the
python-default
resolve when I have explicitly stated to use the
pants-plugins
resolve in the
BUILD
file in `pants-plugins/`:
Copy code
pants_requirements(name="pants", resolve="pants-plugins")
p
Make sure your tests and code are all in the pants-plugins resolve. This is how I do that in the st2 repo: https://github.com/StackStorm/st2/blob/master/pants-plugins/BUILD#L3
q
My plugin is fairly simple and doesn't have any tests. Just
register.py
and `rules.py`:
p
Then your BUILD files under pants-plugins/ only have
python_sources
and
pants_requirements
targets. Either add
resolve="pants-plugins"
to all of those targets (both
python_sources
AND
pants_requirements
, not just
pants_requirements
), or use
__defaults__(all=dict(resolve="pants-plugins"))
in the
pants-plugins/BUILD
file to make sure everything under
pants-plugins/
ends up in the correct resolve.
q
oh I see. I assumed
pants_requirements
adds the
resolve="pants-plugins"
for all the python sources?
p
nope. 🙂
q
According to the docs,
pants_requirements
generates a
python_requirement
target for pants dependencies. Shouldn't that be enough?
p
It generates the
python_requirement
targets, yes. But that does not change the metadata on any of the
python_source
or
python_sources
targets. Since the
python_source*
targets don't specify a resolve, they default to the value of
[python].default_resolve
, which is
python-default
in your case: https://www.pantsbuild.org/2.21/reference/subsystems/python#default_resolve
defining one target rarely affects how another target is configured. So, using
__defaults__
makes it much easier to adjust the metadata for many targets at once.
q
Oh I see. So
python_requirement
just defines what third party dependencies are being used (by pointing to a resolve) but
python_source
needs to also point to a resolve to understand this?
👍 2
p
q
Thank you!
p
The docs describe a "resolve" as being a "universe of third-party dependencies" where each dependency is represented by a
python_requirement
target in that resolve: https://www.pantsbuild.org/2.21/docs/python/overview/third-party-dependencies#teaching-pants-your-universes-of-dependencies To use them, the sources have to be in the same resolve. Hmm. I found an example in the docs of
python_sources(resolve=...
, but it is kind of buried: https://www.pantsbuild.org/2.21/docs/python/overview/lockfiles#multiple-lockfiles
q
I see. I have a follow up question. What if my code has conditional imports? Because I am getting a similar error with that:
p
Your pants-plugins code should always run under python3.9 since that is the only version pants supports right now. There are plans to bump that to 3.11, but I'm not sure how close we are to doing that. So, you can simplify your code and drop the python < 3.9 block. To make sure pants will only use 3.9 when linting/checking your pants-plugins code, you need to add interpreter constraints. In
pants.toml
do something like:
Copy code
[python.resolves]
pants-plugins = "path/to/lock"

[python.resolves_to_interpreter_constraints]
pants-plugins = ["CPython==3.9.*"]
like this: https://github.com/StackStorm/st2/blob/master/pants.toml#L136-L141 And then you will probably also need to add
interpreter_constraints=["CPython==3.9.*"]
in
pants-plugins/BUILD
like this: https://github.com/StackStorm/st2/blob/master/pants-plugins/BUILD#L5
q
Oh sorry for the misunderstanding. This code snippet is not part of the
pants-plugins
. It is part of my project code. Also, according to the docs, it says that the
resolves_to_interpreter_constraints
is used to generate the lockfiles and "this does NOT impact the interpreter constraints used by targets within the resolve". Are there separate
interpreter_constraints
for each resolve? Do I need to make the one for
pants-plugins
3.9.*
?
p
Also, according to the docs, it says that the
resolves_to_interpreter_constraints
is used to generate the lockfiles and "this does NOT impact the interpreter constraints used by targets within the resolve". Are there separate
interpreter_constraints
for each resolve?
Ah yes. I forgot about that being only for lockfile generation. I think it is a good idea to add
__defaults__(all=dict(resolve="pants-plugins", interpreter_constraints=["CPython==3.9.*"]))
in
pants-plugins/BUILD
. If you haven't experienced any issues without that, then go ahead and punt it till later.
As far as the other resolve, what do you have for
[python].interpreter_constraints
in your pants.toml?
q
Copy code
[python]
interpreter_constraints = ["==3.10.12"]
p
So, pants will never run your code with anything other than 3.10.12 then, which means you can drop that python < 3.9 block. If you want to keep the conditional import block, then you can do what the error message suggested and ignore those imports:
Copy code
if sys.version < (3, 9):
    from importlib_resources import files  # pants: no-infer-dep
    from typing_extensions import Protocol, TypeAlias  # pants: no-infer-dep
q
Ohk I see. But if I were using multiple interpreter versions, how would I resolve this issue?
without using the
#pants: no-infer-dep
would i need to have different resolves? one for each interpreter version?
p
Make sure your resolve (probably via a requirements.txt file) includes
importlib-resources
and
typing_extensions
.
Even though
[python].interpreter_constraints
is a list, the list should really only have one item in it. But, you can include a range of versions:
>=3.8,<4
.
q
Oh I see! Yes, I didn't have them in my requirements.txt. Thank you!
p
You'll probably want to use a python_version marker in requirements.txt:
importlib-resources; python_version < '3.9'
q
Yes, thank you!