New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow users to request a fixed python interpreter #4930
Conversation
if fixed_interpreter: | ||
interpreter = PythonInterpreter.from_binary(fixed_interpreter) | ||
else: | ||
python_tgts = self.context.targets(lambda tgt: isinstance(tgt, PythonTarget)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use GitHub's secret whitespace ignore option to see that I haven't actually changed any of this: https://github.com/pantsbuild/pants/pull/4930/files?w=1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Neat! Didn't know that existed. Although I'm not sure what that does exactly, esp. where whitespace is meaningful.
Anyway, might be better to split this branch off into a separate method, for readability.
46bbe64
to
8689dda
Compare
I'm torn between calling the option |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the contribution! See comments inline.
@@ -41,6 +41,11 @@ class SelectInterpreter(Task): | |||
"""Select an Python interpreter that matches the constraints of all targets in the working set.""" | |||
|
|||
@classmethod | |||
def register_options(cls, register): | |||
super(SelectInterpreter, cls).register_options(register) | |||
register('--fixed-interpreter', type=str, help='Use this Python interpreter instead of searching based on constraints', default=None) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this option should be in python_setup.py along so it's next to --interpreter-constraints
?
Also, if I understand correctly the value here should be a path to a python
binary? Let's update the help text to clarify this (i.e., what "this Python interpreter" means...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure! I thought of doing that but then I don't know how to get the constraints option from there to here. I haven't figured out yet how the current top-level constraints propagate yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I need to use the global_instance
I think. Okay, I'll push an update doing all that!
if fixed_interpreter: | ||
interpreter = PythonInterpreter.from_binary(fixed_interpreter) | ||
else: | ||
python_tgts = self.context.targets(lambda tgt: isinstance(tgt, PythonTarget)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Neat! Didn't know that existed. Although I'm not sure what that does exactly, esp. where whitespace is meaningful.
Anyway, might be better to split this branch off into a separate method, for readability.
8689dda
to
6768dad
Compare
@benjyw I pushed a new version that (I think) addresses your comments. I haven't run the tests or anything on it yet, but it seems to work fine on my local installation |
@@ -62,13 +62,19 @@ def register_options(cls, register): | |||
register('--artifact-cache-dir', advanced=True, default=None, metavar='<dir>', | |||
help='The parent directory for the python artifact cache. ' | |||
'If unspecified, a standard path under the workdir is used.') | |||
register('--fixed-interpreter', advanced=True, default=None, metavar='<interpreter-binary>', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should probably be an interpreter search path that's checked against the constraints vs a single interpreter.. in order to support e.g. 2 + 3. we've learned this the hard way with PEX_PYTHON
(vs e.g. PEX_PYTHONS
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I'd pass those paths into interpreter_cache.setup()
? I can do that
6768dad
to
6a4082b
Compare
@kwlzn how's this one? |
@@ -62,13 +62,19 @@ def register_options(cls, register): | |||
register('--artifact-cache-dir', advanced=True, default=None, metavar='<dir>', | |||
help='The parent directory for the python artifact cache. ' | |||
'If unspecified, a standard path under the workdir is used.') | |||
register('--interpreter-search-paths', advanced=True, type=list, default=[], metavar='<binary-paths>', | |||
help='A list of paths in which to search for python') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"To search for python interpreters."
Tiny nit: End the help sentence with a period. For grammar and for consistency...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@benjyw fixed 😄
By default it looks in PATH (the old behavior) but you can now tell it to look elsewhere
6a4082b
to
17d65ee
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this LGTM - how about a quick integration test or two to keep it from regressing later tho?
@kwlzn I wasn't sure how best to test it, since I can't really assume multiple python versions will be present on the test box (or can I?) so it's hard for me to throw together a sample project that would make sure the resolution logic uses the python I want. I could set it to an empty search path and ensure that it complains that it can't find any pythons, but that feels kinda weak. |
@copumpkin fair enough - tho there are some tests that target 2.7 + 3.x so I imagine it'd be possible.. but perhaps a couple too many hoops to jump through. can circle back after #4859 affords us better control over the test execution environment. |
Cool, I'll keep an eye on #4859 then. Thanks again! |
Oh also, should I backport this to the 1.3 branch? That's what I've been using it on in my team, but unsure if you want to put it into an official release. |
Thanks @stuhood ! |
@kwlzn @benjyw @stuhood one thing I'm not sure about is how this should interact with the .pants.d cache of the python interpreter. If I change pants.ini to look for a different python version, I assume the cached python path will get updated, but I don't understand the cache more broadly to figure out how it should know about this option getting passed in. Any of you have any advice? |
Problem In some situations, the automatic python picker logic picks the wrong version of Python and we don't have much control over that beyond being able to specify version constraints (which sometimes aren't sufficient). Solution I added an option to explicitly specify a list of paths to search. Result Users can now pass in --python-setup-interpreter-search-paths=<search-paths> and have Pants search in the specified paths. You can even pass in the full path of the interpreter (e.g., which python) and it'll figure that out!
Problem
In some situations, the automatic python picker logic picks the wrong version of Python and we don't have much control over that beyond being able to specify version constraints (which sometimes aren't sufficient).
Solution
I added an option to explicitly specify a list of paths to search.
Result
Users can now pass in
--python-setup-interpreter-search-paths=<search-paths>
and have Pants search in the specified paths. You can even pass in the full path of the interpreter (e.g.,which python
) and it'll figure that out!