10

I just did:

pipenv install django[argon2]

And this changed my Pipfile:

-django = "==2.1.5"
+django = {extras = ["argon2"],version = "*"}

I want to pin the requirements. First I will pin django to 2.1.5:

django = {extras = ["argon2"],version = "==2.1.5"}

What about argon2? Is that a separate package? There is no such package when I do pip freeze:

$ pip freeze  | grep -i argon2
argon2-cffi==19.1.0

What is that? How do I fully pin django[argon2]?

volingas
  • 1,023
  • 9
  • 21

3 Answers3

7

In my Pipfile, I found this possible by double-quoting the package and the version

[packages]
"django[argon2]" = "==2.1.5"
ti7
  • 16,375
  • 6
  • 40
  • 68
5

From the Requirement Specifier docs for pip, you can combine these forms:

SomeProject == 1.3  
SomeProject >=1.2,<2.0  
SomeProject[foo, bar]

This means you can do this command:

pipenv install "django[argon2]==2.1.5"

Which generates this Pipfile entry:

django = {version = "==2.1.5", extras = ["argon2"]}

That command installs Django and:

  1. Pins Django at version 2.1.5 (or whatever is specified as ==VERSION)
  2. Includes Django's optional support for Argon2

There is no argon2 package. The [argon2] means it is an optional dependency or an optional feature of Django. What gets installed is the argon2-cffi and cffi packages, which are the optional dependencies Django needs to use Argon2. You can see this in the Pipfile.lock:

"argon2-cffi": {
    "hashes": [
        ...
    ],
    "version": "==20.1.0"
},
"cffi": {
    "hashes": [
        ...
    ],
    "version": "==1.14.6"
},
"django": {
    "extras": [
        "argon2"
    ],
    "hashes": [
        ...
    ],
    "index": "pypi",
    "version": "==2.1.5"
},

This is also mentioned in the Django docs:

To use Argon2 as your default storage algorithm, do the following:

  1. This can be done by running python -m pip install django[argon2], which is equivalent to python -m pip install argon2-cffi (along with any version requirement from Django’s setup.cfg)

The difference of doing pipenv install django[argon2] compared to installing django and argon2-cffi separately (as with this other answer) is that, during installation, you let Django's setuptools decide which version of argon2-cffi to use. This is better because the Django maintainers probably wrote and tested the code for Argon2 support using a compatible version of argon2-cffi.

This can be seen in Django's setup.cfg file (for Django 3.2.6 at the time of this writing):

[options.extras_require]
argon2 = argon2-cffi >= 19.1.0

which indicates that when using optional [argon2] feature it needs to install that range of version of argon2-cffi. As James O' Brien commented: "A specific version of django would require specific versions of the extras."

Gino Mempin
  • 25,369
  • 29
  • 96
  • 135
0

If you want full control you can:

pipenv install "django==2.1.5" "argon2-cffi==19.1"

Is it what you need?

Alex Yu
  • 3,412
  • 1
  • 25
  • 38
  • Well, I am not even sure what I am doing with `pip install django[argon2]`, or how that compares to your command. Am I installing two packages? Am I installing a single package (django), with a different flavor? Can I then pin django and argon2 separately? Questions, questions, ... – volingas Feb 08 '19 at 09:26
  • You are installing with setup [extras](https://pip.pypa.io/en/stable/reference/pip_install/#options) (see option 6) described in [setuptools documentation](https://setuptools.readthedocs.io/en/latest/setuptools.html#declaring-extras-optional-features-with-their-own-dependencies). I never quite understood motivation behind extras and it looks as they are not fully supported by pipenv command line. – Alex Yu Feb 08 '19 at 09:41
  • 1
    It probably would not be advisable to pin the extras. A specific version of django would require specific versions of the extras. If you want to see what gets installed, search for `argon2` in the `Pipfile.lock` – James O'Brien May 26 '20 at 18:27