Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PIP Constraints Files

Tags:

python

pip

I was reading the docs and couldn't wrap my head around it:

Constraints files are requirements files that only control which version of a requirement is installed, not whether it is installed or not. Their syntax and contents is nearly identical to Requirements Files.

There is one key difference: Including a package in a constraints file does not trigger installation of the package.

  • So does that mean I need to requirement files first then run constraint?
  • Need to have both requirements.txt and constraints.txt?
  • Or just -c requirements.txt?

Could someone please explain in plain English that what the new PIP feature: Constraints Files does?

like image 353
James Lin Avatar asked Jan 07 '16 01:01

James Lin


People also ask

What is constraints file in pip?

Constraints files are requirements files that only control which version of a requirement is installed, not whether it is installed or not. Their syntax and contents is nearly identical to Requirements Files.

Where is my pip config file?

This location is different on different operating systems, and has some additional complexity for backwards compatibility reasons. In a “pip” subdirectory of any of the paths set in the environment variable XDG_CONFIG_DIRS (if it exists), for example /etc/xdg/pip/pip. conf . This will be followed by loading /etc/pip.

What is pip requirements txt?

Requirements files serve as a list of items to be installed by pip, when using pip install. Files that use this format are often called “pip requirements. txt files”, since requirements. txt is usually what these files are named (although, that is not a requirement).


1 Answers

Update: pip 20.3, released Nov 30, 2020, introduced a new resolver that fixes some design issues. It also reimplements the constraints feature. It is now difficult or impossible to use the feature the way I describe below. I do not understand the new constraints implementation, and I no longer use it. I've had success with pip-compile from pip-tools. I specify top-level requirements in requirements.in, and pip-compile generates a requirements.txt with specific versions an package hashes. See requirements.in and requirements.txt in the ichnaea project for a working example.

Original answer below, for pip 20.2 and previous

I think a constraints file is a good way to keep your "true" requirements separate from your full install list.

It's good practice to fully specify package versions in your requirements file. For example, if you are installing django-allauth with Django LTS, pin it to the latest releases (as of my answer):

Django==1.8.12 django-allauth==0.25.2 

When you install the package, it ends up installing some required packages as well. So, you add those as well, so that everyone gets the same versions of packages:

Django==1.8.12 django-allauth==0.25.2 oauthlib==1.0.3 python-openid==2.2.5 requests==2.9.1 requests-oauthlib==0.6.1 

And then you get the bug report "Doesn't work under Python 3". Oops, python-openid is Python 2 only, and python3-openid is used instead, further requiring defusedxml:

Django==1.8.12 django-allauth==0.25.2 oauthlib==1.0.3 python-openid==2.2.5   ; python_version < '3.0' python3-openid==3.0.10 ; python_version >= '3.0' defusedxml==0.4.1      ; python_version >= '3.0' requests==2.9.1 requests-oauthlib==0.6.1 

Now requirements.txt is getting ugly, and it's hard to see the "requirements" of Django and django-allauth in the mess.

Here is a requirements.txt that refers to a constraints file:

-c constraints.txt Django==1.8.12 django-allauth==0.25.2 

And constraints.txt with a helpful comment:

# django-allauth requirements oauthlib==1.0.3 python-openid==2.2.5 python3-openid==3.0.10 defusedxml==0.4.1 requests==2.9.1 requests-oauthlib==0.6.1 

No Python classifiers are needed, because constraints are only installed if a package requires them, and are ignored otherwise. Additionally, if a package stops requiring another package 2 years down the road, fresh installs will stop installing it.

I think this, plus some comments, is a useful way to communicate what packages you are using for the project, and which ones are included because they are dependencies.

I think it gets even more useful if you are using pip 8.x's hash-checking mode, which requires specifying versions for dependencies-of-dependencies. If you go down that path, I recommend hashin to help you manage the hashes. See browsercompat for a complicated requirements setup using constraints and hashes.

like image 80
jwhitlock Avatar answered Oct 02 '22 12:10

jwhitlock