Reputation: 3519
So far I know requirements.txt like this: Django==2.0
. Now I saw this style of writing Django>=1.8,<2.1.99
Can you explain to me what it means?
Upvotes: 0
Views: 3176
Reputation: 477210
requirements.txt
is a file where one specifies dependencies. For example your program will here depend on Django
(well you probably do not want to implement Django yourself).
In case one only writes a custom application, and does not plan to export it (for example as a library) to other programmers, one can pin the version of the library, for example Django==2.0.1
. Then you can always assume (given pip
manages to install the correct package) that your environment will ave the correct version, and thus that if you follow the correct documentation, no problems will (well should) arise.
If you however implement a library, for example mygreatdjangolibrary
, then you probably do not want to pin the version: it would mean that everybody that wants to use your library would have to install Django==2.0.1
. Imagine that they want a feature that is only available in django-2.1, then they can - given they follow the dependencies strictly - not do this: your library requires 2.0.1. This is of course not manageable.
So typically in a library, one aims to give as much freedom to a user of a library. It would be ideal if regardless of the Django version the user installed, your library could work.
Unfortunately this would result in a lot of trouble for the library developer. Imagine that you have to take into account that a user can use Django-1.1 up to django-2.1. Through the years, several features have been introduced that the library then can not use, since the programmer should be conservative, and take into account that it is possible that these features do not exist in the library the user installed.
It becomes even worse since Django went through some refactoring: some features have later been removed, so we can not simply program on django-1.1 and hope that everything works out.
So in that case, it makes sense to specify a range of versions we support. For example we can read the documentation of django-2.0, and look to the release notes to see if something relevant changed in django-2.1, and let tox
test both versions for the tests we write. We thus then can specify a range like Django>=2.0,<2.1.99
.
This is also important if you depend on several libraries that each a common requirement. Say for example you want to install a library liba
, and a library libb
, both depend on Django, bot the two have a different range, for example:
liba:
Django>=1.10, <2.1
libb:
Django>=1.9, <1.11
Then this thus means that we can only install a Django
version between >=1.10
and <1.11
.
The above even easily gets more complex. Since liba
and libb
of course have versions as well, for example:
liba-0.1:
Django>=1.10, <2.1
liba-0.2:
Django>=1.11, <2.1
liba-0.3:
Django>=1.11, <2.2
libb-0.1:
Django>=1.5, <1.8
libb-0.2:
Django>=1.10, <2.0
So if we now want to install any liba
, and any libb
, we need to find a version of liba
and libb
that "allows" us to install a Django
version, and that is not that trivial since for example if we would pick libb-0.1
, then there is no version of liba
that supports an "overlapping" Django version.
To the best of my knowledge, pip
currently has no dependency resolution algorithm. It looks at the specification, and each time aims to pick the most recent that is satisfying the constraints, and recursively installs the dependencies of these packages.
Therefore it is up to the user to make sure that (sub)dependencies do not conflict: if we would specify liba
libb==0.1
, then pip
will probably install Django-2.1
, and then find out that libb
can not work with this.
There are some dependency resolution programs. But the problem turns out to be quite hard (it is NP-hard if I recall correctly). So that means that for a given dependency tree, it can takes years to find a valid configuration.
Upvotes: 1