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

Support using pip-compile generated file header to choose Python version #4216

Closed
honnix opened this issue Sep 10, 2021 · 7 comments · Fixed by #8280
Closed

Support using pip-compile generated file header to choose Python version #4216

honnix opened this issue Sep 10, 2021 · 7 comments · Fixed by #8280
Labels
L:python:pip-compile Python packages via pip-compile T: feature-request Requests for new features

Comments

@honnix
Copy link
Contributor

honnix commented Sep 10, 2021

Since https://github.com/jazzband/pip-tools/releases/tag/6.2.0 pip-compile logs Python version (up to minor version) in the generated file, for example This file is autogenerated by pip-compile with python 3.6.

This information could be used to deduce which Python version to use when executing pip-compile before falling back to the default one. I think it has higher accuracy than trying to read python_version marker from generated file because using python_version marker in *.in file does not necessarily mean it gets compiled under a Python version that satisfies the marker.

@honnix honnix added the T: feature-request Requests for new features label Sep 10, 2021
seanh added a commit to hypothesis/lms that referenced this issue Aug 11, 2022
As far as I know `pip-compile` only needs to be run with the right
version of Python, it doesn't actually need to be run in the same
virtualenv that the requirements file is (or will be) installed in.

IIRC the only reason why I did use `tox` to run `pip-compile` in the
first place was that we might have a project that uses different Python
versions for different virtualenvs. For example we did this in the past
with legacy Via: Via itself only supported Python 2 so virtualenvs like
dev, tests, functests, etc used Python 2. But the Black code formatter
could only be run in Python 3 (even though it could format Python 2
code) so we used Python 3 for the format virtualenv. Generally speaking
the ability to have different tox environments using different Python
versions enables us to adopt a tool like formatter or linter without
that tooling necessarily having to be run with the same version of
Python that the app runs in.

But:

1. We don't currently have any apps that use multiple Python versions in
   this way.

2. As far as I know using multiple Python versions with `pip-compile`'d
   requirements files isn't compatible with Dependabot: Dependabot will
   use the first Python version from your `.python-version` to compile
   *all* your `requirements.txt` so it'll break any `requirements.txt`
   files that use a different Python version.

   I don't understand the Dependabot Ruby source code well enough to
   verify whether this is still the case but last time I tested it was
   and there are still multiple open issues about this on Dependabot's
   GitHub issues, for example
   dependabot/dependabot-core#4216
   and dependabot/dependabot-core#4607

   I'm not sure how we got away with this when legacy Via used multiple
   Python versions. I suspect maybe it wasn't using Dependabot?

I think we should just consider leaning in to the fact that while our
Python _packages_ can support multiple Python versions because they
don't use `pip-compile` and don't have pinned requirements files, our
_apps_ can only support one version of Python at a time (one version
shared by all their tox envs).

If we're willing to make that assumption we can simplify the
implementation of `make requirements`, which is what this commit does.
seanh added a commit to hypothesis/lms that referenced this issue Aug 11, 2022
`pip-compile` only needs to be run with the right version of Python, it
doesn't actually need to be run in the same virtualenv that the
requirements file is (or will be) installed in.

IIRC the only reason why I did use `tox` to run `pip-compile` in the
first place was that we might have a project that uses different Python
versions for different virtualenvs. For example we did this in the past
with legacy Via: Via itself only supported Python 2 so virtualenvs like
dev, tests, functests, etc used Python 2. But the Black code formatter
could only be run in Python 3 (even though it could format Python 2
code) so we used Python 3 for the format virtualenv. Generally speaking
the ability to have different tox environments using different Python
versions enables us to adopt a tool like a formatter or linter without
that tool necessarily having to be run with the same version of Python
that the app runs in.

But:

1. We don't currently have any apps that use multiple Python versions in
   this way.

2. As far as I know using multiple Python versions with `pip-compile`'d
   requirements files isn't compatible with Dependabot: Dependabot will
   use the first Python version from your `.python-version` to compile
   *all* your `requirements.txt` files so it'll break any
   `requirements.txt` files that use a different Python version.

   I don't understand the Dependabot Ruby source code well enough to
   verify whether this is still the case without actually trying it but
   [last time I tested](https://github.com/seanh/python-multiversion-dependency-management-demo#dependabot-)
   it was and there are still multiple open issues about this on
   Dependabot's GitHub issues, for example
   dependabot/dependabot-core#4216 and
   dependabot/dependabot-core#4607

   I think it may be possible to get Dependabot to use the right Python
   version if you put different requirements files in different subdirs
   and give each subdir its own `.python-version` file. But I haven't
   tested this and I don't think we want to do it.

   I'm not sure how we got away with this when legacy Via used multiple
   Python versions. I suspect maybe it wasn't using Dependabot?

I think we should consider leaning in to the fact that while our Python
_packages_ can support multiple Python versions because they don't use
`pip-compile` and don't have pinned requirements files, our _apps_ can
only support one version of Python at a time (one version shared by all
their tox envs).

If we're willing to make that assumption we can simplify the
implementation of `make requirements`, which is what this commit does.
@jeffwidman jeffwidman added the L: python:pip Python packages via pip label Nov 24, 2022
@jeffwidman
Copy link
Member

jeffwidman commented Nov 24, 2022

👋 Interesting idea.

What do you think about moving more toward extracting the python version from pyproject.toml?

That seems to be the way a lot of tooling in the python ecosystem is moving, so is a solution that's more generic than pip-compile... and I think we already do that today.

@honnix
Copy link
Contributor Author

honnix commented Nov 26, 2022

👋 Interesting idea.

What do you think about moving more toward extracting the python version from pyproject.toml?

That seems to be the way a lot of tooling in the python ecosystem is moving, so is a solution that's more generic than pip-compile... and I think we already do that today.

Yeah I think that makes sense. I'm not sure there is a standard way to define python version in pyproject.toml though. It might be OK to take the lower bound of python_requires.

@bmerry
Copy link

bmerry commented Jan 10, 2023

What do you think about moving more toward extracting the python version from pyproject.toml?

That wouldn't solve the use case where there are multiple lockfiles each targeting a different Python version (see #4607).

@deivid-rodriguez deivid-rodriguez added L:python:pip-compile Python packages via pip-compile and removed L: python:pip Python packages via pip labels Jan 10, 2023
@deivid-rodriguez
Copy link
Contributor

I think parsing the python version from the header and using that as proposed would be the most reliable way to update pip-compile generated files. My understanding is that while pyproject.toml acts like a manifest ("this library/application supports this range of python versions"), the requirements.txt file generated by pip-compile acts like a lockfile ("this file was generated by this specific python version").

@webknjaz
Copy link

webknjaz commented Feb 4, 2023

The Python version is just one small part of the problem. How about the platform/arch factors? #4607

@bmerry
Copy link

bmerry commented Nov 24, 2023

@deivid-rodriguez thanks for implementing this. Do you know how to tell whether it's deployed to Github yet? I just tried it on a Github project, and it doesn't seem to have worked. It opened ska-sa/spead2#291, where the top of the file indicates Python 3.12, but it's pulled in packages that the requirements.in indicates are only for use with <3.12.

@deivid-rodriguez
Copy link
Contributor

It's deployed already. Can you open a separate issue? Handling markers may require extra tricks, not sure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
L:python:pip-compile Python packages via pip-compile T: feature-request Requests for new features
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants