Skip to content
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

slightly demystify the relationship between platforms and interpreters in the library API and CLI #1047

Conversation

cosmicexplorer
Copy link
Contributor

@jsirois read my mind in #1033 (comment) after I asked why Pex couldn't resolve for an interpreter it doesn't have locally. This was in fact already possible, and he suggested a documentation fix to make it more clear. These changes make it clear that:

  • platform{,s} takes precedence over interpreter{,s} when resolving wheels
  • interpreter{,s} are used to seed platform{,s} if not provided
  • matching interpreter{,s} must be provided for all platform{,s} if any distributions need to be built from source

Closes #1033.

@cosmicexplorer cosmicexplorer added enhancement resolver API Issues that relate to changes in the public Pex API labels Sep 27, 2020
Copy link
Member

@jsirois jsirois left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. I'm still not sure you and the API are on the same page. More clarification below.

pex/resolver.py Outdated Show resolved Hide resolved
@cosmicexplorer
Copy link
Contributor Author

cosmicexplorer commented Sep 28, 2020

Ok, I've made another change to the docstring. In this case I have:

  • clearly specified that distributions are resolved for interpreters as well as platforms, but that the current interpreter is used to build any non-wheel distributions for platforms.
  • added (correctly) two :raises ValueError: clauses in resolve(), resolve_multi(), and download() to clarify what happens when you don't allow building non-wheels and don't allow building wheels.

My final question is: is it possible to successfully build wheels for foreign platforms from pure-python libraries that are only provided as .tar.gz? This would occur e.g. if you wanted to build a PEX containing a linux dist of tensorflow==1.14.0 from a mac. It appears pip stops you from doing this too, but it feels artificial. Not sure if I'm missing some reason this is truly incompatible here.

EDIT: ah, it appears the .tar.gz dists I'm finding do actually compile native code. Not sure if there's actually anything wrong here.

pex/bin/pex.py Outdated
"composed of fields: <platform>-<python impl abbr>-<python version>-<abi>. These fields "
"stem from wheel name conventions as outlined in "
"interpreter you can pass `current` "
"(which is the default value if this option is not provided). "
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parenthetical contradicts the default above and its not always true either. Consider the case where 1 interpreter is specified - say via --python python2.7 and yet the Pex CLI is running under Python 3.6. In that case the resulting PEX file will only be built using a local Python 2.7 interpreter and not additionally for current which is a local Python 3.6 interpreter. How about just dropping this addition?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for explaining this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After reverting the change you noted, I modified this further to include the distinction you gave above:

If any distributions need to be built, use the --python or --interpreter-constraint argument instead, providing the corresponding interpreter.

pex/resolver.py Outdated
:keyword str platform: The exact target platform to resolve distributions for. If ``None`` or
``'current'``, resolve for distributions appropriate for `interpreter`.
:keyword str platform: The exact PEP425-compatible platform string to resolve distributions for,
in addition to the platform of the given interpreter, if provided. The current interpreter
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current interpreter will be used to build any non-wheel distributions.

This is not true. If non-wheel distributions are encountered when resolving for the given platform, resolution will fail.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps the confusion is that the CLI, which uses the API, will turn --platform ... arguments into PythonInterpreters when ---resolve-local-platforms. It then passes interpreters for those platforms it could resolve instead of passing platforms. Does that clear things up? I.E.: --resolve-local-platforms is a CLI feature and not a resolve API feature.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if the platform matches the supported_tags of the current interpreter? I'm looking at

We raced each other. I think you're confusing a CLI feature for an API feature. Let me know if I've guessed your confusion or if it persists.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which isn't exactly rare, now that I think of it -- I believe platform='current' would do the trick. I think it would be useful to add the sentence I proposed above, but if that seems like too much information I'm not beholden to it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah! But we have a specific check for that! https://github.com/pantsbuild/pex/blob/e67412c31648f6e0d0f2a68b9d38dffabb258ebc/pex/resolver.py#L972-L974

It seems like we might want to consider expanding that check to cover when the platform matches any of the given interpreters, in addition to checking if it's just None. I don't know if there's any deduplication later. I'll test out what happens if you give an explicit platform string matching the current interpreter.

Copy link
Member

@jsirois jsirois Sep 28, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're losing me. The block of code you point to just ensures that for platforms=[None] (which is how parsed_platforms translates platforms=['current']) and interpreters=None or interpreters=[] we use the current interpreter as the single interpreter to resolve with.

The general search you describe is what the CLI does in the code I pointed to above in pex/bin/pex.py when you sepcify --resolve-local-platforms.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want to document the edge case where platforms=['X', ...] and 'X' happens to match the current interpreter accessing the Pex API, that's fine with me. But, to be clear, 'X' could either be 'current' in that case or a full platform string that just happens to match the current interpreter.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, thank you for piecing that together. Let me know if 2fc5078 seems sufficient to document that.

pex/resolver.py Outdated Show resolved Hide resolved
@cosmicexplorer cosmicexplorer force-pushed the make-platforms-more-obvious-in-resolve-docstring branch 2 times, most recently from 3e79102 to ca80d0d Compare September 28, 2020 03:17
pex/resolver.py Outdated Show resolved Hide resolved
@cosmicexplorer cosmicexplorer force-pushed the make-platforms-more-obvious-in-resolve-docstring branch from ca80d0d to 2fc5078 Compare September 28, 2020 03:30
pex/bin/pex.py Outdated Show resolved Hide resolved
pex/bin/pex.py Outdated
@@ -533,7 +536,8 @@ def configure_clp_pex_environment(parser):
"compatible Python version. Normally, when multiple interpreters match, Pex will "
"resolve requirements for each interpreter; this allows the resulting Pex to be "
"compatible with more interpreters, such as different Python versions. However, "
"resolving for multiple interpreters results in worse performance."
"resolving for multiple interpreters will take longer to build, and the resulting PEX "
"will be larger."
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/will be/may be/ - the tarpit again. It will only be larger if there are wheels that vary. If its a pure universal wheel resolve for example, this is false as is.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My only concern with the original wording is that I might be worried upon reading the help for the first time that there's e.g. some weird bug, or some complex emergent effect, that causes multi-interpreter PEX files to run more slowly. I would have left it at "takes longer to build", but there is at least one runtime effect -- namely the file size (which as you pointed out is not guaranteed to differ -- have implemented your edit).

I think that too much information, especially in CLI help, can absolutely be overwhelming (and I know I am prone to causing this more than others). I would be fine reverting this too, although I think this one is much more defensible than the change to --platform help that I just reverted.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah - this is a smell of the feature. It was added for Pants use but does not make much sense for Pex use. It's in fact still buggy and will only be fixed #1020. That said, Eric and I came to light agreement on killing the feature since Pants no longer uses it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, that sounds fine then. I'll perhaps leave this change in then just to be done with it, but from what I can tell killing the feature seems quite reasonable. In the future I suspect that Pants could make use of checked-in python scripts like ipex_launcher.py to make Pex tools that work with the process execution framework (and avoid churn in the upstream Pex project).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, I'm cool with removing it.

@cosmicexplorer cosmicexplorer merged commit 0e1d3df into pex-tool:master Sep 28, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
API Issues that relate to changes in the public Pex API enhancement resolver
Projects
None yet
Development

Successfully merging this pull request may close these issues.

specify (interpreter-constraint) x (platform), and pass --python-version to pip regardless of a local binary
3 participants