jazzband / pip-tools

A set of tools to keep your pinned Python dependencies fresh.
https://pip-tools.rtfd.io
BSD 3-Clause "New" or "Revised" License
7.6k stars 607 forks source link

Consider downstream python version pins when generating requirements.txt #2102

Closed ChrisHills463 closed 4 weeks ago

ChrisHills463 commented 4 weeks ago

What's the problem this feature will solve?

When generating requirements.txt for a package which has multiple pinned Python version dependencies, then these should be taken into account when generating requirements.txt.

For instance, the package botocore contains the following in setup.py (note the multiple entries for package urllib3):-

requires = [
    'jmespath>=0.7.1,<2.0.0',
    'python-dateutil>=2.1,<3.0.0',
    # Prior to Python 3.10, Python doesn't require openssl 1.1.1
    # but urllib3 2.0+ does. This means all botocore users will be
    # broken by default on Amazon Linux 2 and AWS Lambda without this pin.
    'urllib3>=1.25.4,<1.27 ; python_version < "3.10"',
    'urllib3>=1.25.4,!=2.2.0,<3 ; python_version >= "3.10"',
]

Describe the solution you'd like

Generating requirements for the package botocore depends upon the version of Python that is currently running, and so the generated file may not be usable by other Python versions.

Here is an example:-

echo botocore > requirements.in
python3.9 -m piptools compile requirements.in --generate-hashes --no-annotate --no-header 2>&1 | tail -n 3

urllib3==1.26.19 \
    --hash=sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472 \
    --hash=sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168

The generated requirements.txt file will not be usable with Python >= 3.10.

Similarly, the following will result in a requirements.txt file that is not usable with Python < 3.10:-

echo botocore > requirements.in
python3.10 -m piptools compile requirements.in --generate-hashes --no-annotate --no-header 2>&1 | tail -n 3

urllib3==2.2.2 \
    --hash=sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472 \
    --hash=sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168

My desired solution is for the resulting file to contain the following:-

urllib3==1.26.19 ; python_version < "3.10" \
    --hash=sha256:37a0344459b199fce0e80b0d3569837ec6b6937435c5244e7fd73fa6006830f3 \
    --hash=sha256:3e3d753a8618b86d7de333b4223005f68720bcd6a7d2bcb9fbd2229ec7c1e429
urllib3==2.2.2 ; python_version >= "3.10" \
    --hash=sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472 \
    --hash=sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168

Alternative Solutions

For now, I manually alter the generated file to add both package versions with the Python version pins.

Additional context

N/A

AndydeCleyre commented 4 weeks ago

Thanks! This looks like a duplicate of #826, but let me know if I missed something.