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

setuptools, pip and wheel always in latest version? #2364

Closed
dvzrv opened this issue Jun 15, 2018 · 41 comments · Fixed by #5275
Closed

setuptools, pip and wheel always in latest version? #2364

dvzrv opened this issue Jun 15, 2018 · 41 comments · Fixed by #5275
Assignees
Labels
Status: Needs More Information This issue does not provide enough information to take further action.

Comments

@dvzrv
Copy link

dvzrv commented Jun 15, 2018

With current pipenv (2018.5.18, installed with brew, but same behavior also observed on Windows), I'm unable to version-pin setuptools, pip or wheel. However, the circumstances require it to be version pinned, as other tools (twine) will otherwise try to upload a metainfo version they can not cope with to an artifactory instance. Installing setuptools and wheel in a specific version globally/per-user fixes this, but that's also not a solution for our build environment.

pipenv --version
pipenv, version 11.0.2

(btw. the version scheme is still wrong in the --version output! :-)).

Why are these packages excluded from version pinning and can and/or will this be changed?


Expected result

Be able to install setuptools, wheel and pip in pinned versions.

Actual result

setuptools, pip, wheel get installed in their latest version, no matter what.

Steps to replicate

Pipfile

[dev-packages]
setuptools  = "<=38.5.2"
wheel       = "0.30.0"
pytest      = "*"
pytest-mock = "*"
pytest-cov  = "*"
coverage    = "*"
mock        = "*"

[packages]
gitpython = "*"
pyyaml = "*"
appdirs = "*"

Pipfile.lock

{
    "_meta": {
        "hash": {
            "sha256": "7fa7214c22ccb6a7e1832afa5228734452bccea95d8c30bedb51cead085e95a6"
        },
        "pipfile-spec": 6,
        "requires": {},
        "sources": [
            {
                "name": "pypi",
                "url": "http://10.1.11.198/artifactory/api/pypi/ni-python-all/simple",
                "verify_ssl": false
            }
        ]
    },
    "default": {
        "appdirs": {
            "hashes": [
                "sha256:9e5896d1372858f8dd3344faf4e5014d21849c756c8d5701f78f8a103b372d92",
                "sha256:d8b24664561d0d34ddfaec54636d502d7cea6e29c3eaf68f3df6180863e2166e"
            ],
            "version": "==1.4.3"
        },
        "gitdb2": {
            "hashes": [
                "sha256:b60e29d4533e5e25bb50b7678bbc187c8f6bcff1344b4f293b2ba55c85795f09",
                "sha256:cf9a4b68e8c4da8d42e48728c944ff7af2d8c9db303ac1ab32eac37aa4194b0e"
            ],
            "version": "==2.0.3"
        },
        "gitpython": {
            "hashes": [
                "sha256:1ec4c44846cf76a1e55769560673a97731849c9d05401e035e607495f10db959",
                "sha256:b60b045cf64a321e5b620debb49890099fa6c7be6dfb7fb249027e5d34227301"
            ],
            "version": "==2.1.10"
        },
        "pyyaml": {
            "hashes": [
                "sha256:16b20e970597e051997d90dc2cddc713a2876c47e3d92d59ee198700c5427736",
                "sha256:3262c96a1ca437e7e4763e2843746588a965426550f3797a79fca9c6199c431f",
                "sha256:592766c6303207a20efc445587778322d7f73b161bd994f227adaa341ba212ab",
                "sha256:5ac82e411044fb129bae5cfbeb3ba626acb2af31a8d17d175004b70862a741a7",
                "sha256:827dc04b8fa7d07c44de11fabbc888e627fa8293b695e0f99cb544fdfa1bf0d1",
                "sha256:bc6bced57f826ca7cb5125a10b23fd0f2fff3b7c4701d64c439a300ce665fff8",
                "sha256:c01b880ec30b5a6e6aa67b09a2fe3fb30473008c85cd6a67359a1b15ed6d83a4",
                "sha256:e863072cdf4c72eebf179342c94e6989c67185842d9997960b3e69290b2fa269"
            ],
            "version": "==3.12"
        },
        "smmap2": {
            "hashes": [
                "sha256:b78ee0f1f5772d69ff50b1cbdb01b8c6647a8354f02f23b488cf4b2cfc923956",
                "sha256:c7530db63f15f09f8251094b22091298e82bf6c699a6b8344aaaef3f2e1276c3"
            ],
            "version": "==2.0.3"
        }
    },
    "develop": {
        "atomicwrites": {
            "hashes": [
                "sha256:240831ea22da9ab882b551b31d4225591e5e447a68c5e188db5b89ca1d487585",
                "sha256:a24da68318b08ac9c9c45029f4a10371ab5b20e4226738e150e6e7c571630ae6"
            ],
            "version": "==1.1.5"
        },
        "attrs": {
            "hashes": [
                "sha256:4b90b09eeeb9b88c35bc642cbac057e45a5fd85367b985bd2809c62b7b939265",
                "sha256:e0d0eb91441a3b53dab4d9b743eafc1ac44476296a2053b6ca3af0b139faf87b"
            ],
            "version": "==18.1.0"
        },
        "coverage": {
            "hashes": [
                "sha256:03481e81d558d30d230bc12999e3edffe392d244349a90f4ef9b88425fac74ba",
                "sha256:0b136648de27201056c1869a6c0d4e23f464750fd9a9ba9750b8336a244429ed",
                "sha256:198626739a79b09fa0a2f06e083ffd12eb55449b5f8bfdbeed1df4910b2ca640",
                "sha256:28b2191e7283f4f3568962e373b47ef7f0392993bb6660d079c62bd50fe9d162",
                "sha256:2eb564bbf7816a9d68dd3369a510be3327f1c618d2357fa6b1216994c2e3d508",
                "sha256:337ded681dd2ef9ca04ef5d93cfc87e52e09db2594c296b4a0a3662cb1b41249",
                "sha256:3a2184c6d797a125dca8367878d3b9a178b6fdd05fdc2d35d758c3006a1cd694",
                "sha256:3c79a6f7b95751cdebcd9037e4d06f8d5a9b60e4ed0cd231342aa8ad7124882a",
                "sha256:3d72c20bd105022d29b14a7d628462ebdc61de2f303322c0212a054352f3b287",
                "sha256:3eb42bf89a6be7deb64116dd1cc4b08171734d721e7a7e57ad64cc4ef29ed2f1",
                "sha256:4635a184d0bbe537aa185a34193898eee409332a8ccb27eea36f262566585000",
                "sha256:56e448f051a201c5ebbaa86a5efd0ca90d327204d8b059ab25ad0f35fbfd79f1",
                "sha256:5a13ea7911ff5e1796b6d5e4fbbf6952381a611209b736d48e675c2756f3f74e",
                "sha256:69bf008a06b76619d3c3f3b1983f5145c75a305a0fea513aca094cae5c40a8f5",
                "sha256:6bc583dc18d5979dc0f6cec26a8603129de0304d5ae1f17e57a12834e7235062",
                "sha256:701cd6093d63e6b8ad7009d8a92425428bc4d6e7ab8d75efbb665c806c1d79ba",
                "sha256:7608a3dd5d73cb06c531b8925e0ef8d3de31fed2544a7de6c63960a1e73ea4bc",
                "sha256:76ecd006d1d8f739430ec50cc872889af1f9c1b6b8f48e29941814b09b0fd3cc",
                "sha256:7aa36d2b844a3e4a4b356708d79fd2c260281a7390d678a10b91ca595ddc9e99",
                "sha256:7d3f553904b0c5c016d1dad058a7554c7ac4c91a789fca496e7d8347ad040653",
                "sha256:7e1fe19bd6dce69d9fd159d8e4a80a8f52101380d5d3a4d374b6d3eae0e5de9c",
                "sha256:8c3cb8c35ec4d9506979b4cf90ee9918bc2e49f84189d9bf5c36c0c1119c6558",
                "sha256:9d6dd10d49e01571bf6e147d3b505141ffc093a06756c60b053a859cb2128b1f",
                "sha256:be6cfcd8053d13f5f5eeb284aa8a814220c3da1b0078fa859011c7fffd86dab9",
                "sha256:c1bb572fab8208c400adaf06a8133ac0712179a334c09224fb11393e920abcdd",
                "sha256:de4418dadaa1c01d497e539210cb6baa015965526ff5afc078c57ca69160108d",
                "sha256:e05cb4d9aad6233d67e0541caa7e511fa4047ed7750ec2510d466e806e0255d6",
                "sha256:f3f501f345f24383c0000395b26b726e46758b71393267aeae0bd36f8b3ade80"
            ],
            "version": "==4.5.1"
        },
        "mock": {
            "hashes": [
                "sha256:5ce3c71c5545b472da17b72268978914d0252980348636840bd34a00b5cc96c1",
                "sha256:b158b6df76edd239b8208d481dc46b6afd45a846b7812ff0ce58971cf5bc8bba"
            ],
            "version": "==2.0.0"
        },
        "more-itertools": {
            "hashes": [
                "sha256:2b6b9893337bfd9166bee6a62c2b0c9fe7735dcf85948b387ec8cba30e85d8e8",
                "sha256:6703844a52d3588f951883005efcf555e49566a48afd4db4e965d69b883980d3",
                "sha256:a18d870ef2ffca2b8463c0070ad17b5978056f403fb64e3f15fe62a52db21cc0"
            ],
            "version": "==4.2.0"
        },
        "pbr": {
            "hashes": [
                "sha256:3747c6f017f2dc099986c325239661948f9f5176f6880d9fdef164cb664cd665",
                "sha256:a9c27eb8f0e24e786e544b2dbaedb729c9d8546342b5a6818d8eda098ad4340d"
            ],
            "version": "==4.0.4"
        },
        "pluggy": {
            "hashes": [
                "sha256:7f8ae7f5bdf75671a718d2daf0a64b7885f74510bcd98b1a0bb420eb9a9d0cff",
                "sha256:d345c8fe681115900d6da8d048ba67c25df42973bda370783cd58826442dcd7c",
                "sha256:e160a7fcf25762bb60efc7e171d4497ff1d8d2d75a3d0df7a21b76821ecbf5c5"
            ],
            "version": "==0.6.0"
        },
        "py": {
            "hashes": [
                "sha256:29c9fab495d7528e80ba1e343b958684f4ace687327e6f789a94bf3d1915f881",
                "sha256:983f77f3331356039fdd792e9220b7b8ee1aa6bd2b25f567a963ff1de5a64f6a"
            ],
            "version": "==1.5.3"
        },
        "pytest": {
            "hashes": [
                "sha256:26838b2bc58620e01675485491504c3aa7ee0faf335c37fcd5f8731ca4319591",
                "sha256:32c49a69566aa7c333188149ad48b58ac11a426d5352ea3d8f6ce843f88199cb"
            ],
            "version": "==3.6.1"
        },
        "pytest-cov": {
            "hashes": [
                "sha256:03aa752cf11db41d281ea1d807d954c4eda35cfa1b21d6971966cc041bbf6e2d",
                "sha256:890fe5565400902b0c78b5357004aab1c814115894f4f21370e2433256a3eeec"
            ],
            "version": "==2.5.1"
        },
        "pytest-mock": {
            "hashes": [
                "sha256:53801e621223d34724926a5c98bd90e8e417ce35264365d39d6c896388dcc928",
                "sha256:d89a8209d722b8307b5e351496830d5cc5e192336003a485443ae9adeb7dd4c0"
            ],
            "version": "==1.10.0"
        },
        "six": {
            "hashes": [
                "sha256:70e8a77beed4562e7f14fe23a786b54f6296e34344c23bc42f07b15018ff98e9",
                "sha256:832dc0e10feb1aa2c68dcc57dbb658f1c7e65b9b61af69048abc87a2db00a0eb"
            ],
            "version": "==1.11.0"
        }
    }
}

pipenv install

pipenv run pip3 list

Package    Version
---------- -------
appdirs    1.4.3
gitdb2     2.0.3
GitPython  2.1.10
pip        10.0.1
PyYAML     3.12
setuptools 39.2.0
smmap2     2.0.3
wheel      0.31.1
@uranusjr
Copy link
Member

uranusjr commented Jun 15, 2018

I don’t think Pipenv did anything here, and I even filed #1884 specifically because it’s not very convenient to upgrade them. IIRC there is some code to explicitly prevent Pipenv from touching them during installation.

Maybe you can try pipenv run pip install setuptools<=38.5.2 and see if pipenv install updates it? Also you may want to check how they are locked in Pipfile.lock.

@uranusjr uranusjr added the Status: Needs More Information This issue does not provide enough information to take further action. label Jun 15, 2018
@dvzrv
Copy link
Author

dvzrv commented Jun 15, 2018

@uranusjr Thanks for the reply! I added the .lock file (must have overread that part, as I only added the Pipfile). As you can see there, setuptools does not get locked. Neither does wheel.

Force installing a different version after the venv got created indeed works as a workaround, but it would be much saner to allow version pinning with pipenv in the Pipfile for these packages, too.

@techalchemy
Copy link
Member

Like most packaging tools, pipenv depends upon you having pip and setuptools. As a consequence it also doesn’t allow you to alter which versions of these things you have in your environment using pipenv itself. If pipenv were able to touch these or allowed you to do that, it would be very easy to destroy your environment. I appreciate that in this specific use case of having an outdated artifactory in a distributed system where you don’t want to tell people to run a manual step, it would be more convenient, but in most other cases the behavior as designed is desirable.

@dvzrv
Copy link
Author

dvzrv commented Jun 15, 2018

@techalchemy well, I just require setuptools to be in a different version. This is not the same as it not being around at all.
If I want to set a different version intentionally, this should be possible.

@dvzrv
Copy link
Author

dvzrv commented Jun 15, 2018

@techalchemy also, this is not about setting my global version of setuptools, but the setuptools version, that will be installed into the virtual environment I'm setting up with pipenv.
I don't understand, why the latest version of setuptools and wheel is forced upon every single virtual environment here.
This renders pipenv completely useless in some use-cases and on top makes its use completely ambivalent, as I'm able to install whatever version of tool I want into said virtual environment after creating it anyhow.
What would be the difference to allowing proper versioning of the base tools I require in the virtual environment to begin with, instead of having the user jump through hoops?

A sane default is of course to choose the latest version of those base tools, but if the user specifically defines a version for them, this should not be ignored!

@uranusjr
Copy link
Member

uranusjr commented Jun 15, 2018

I agree we need to protect certain core packages, but I would tend to agree with @dvzrv here. We should assume the user knows what (s)he’s doing if those packages are explicitly listed in Pipfile.

@techalchemy
Copy link
Member

Anything that allows you to alter setuptools can break pipenv fundamentally. I see no reason to build in support for our tools to break themselves.

this is not about setting my global version of setuptools, but the setuptools version, that will be installed into the virtual environment[..] I don't understand, why the latest version of setuptools and wheel is forced upon every single virtual environment here.

  1. It is absolutely about your global version of setuptools, because
  2. Pipenv doesn’t force anything on your virtualenv. The version of setuptools that lands there is the one you have installed globally.

What you’re asking for is for us to build in support for dependency resolution that permits the resolver to return values that could break our own tools. We aren’t going to do that — if everyone internally is pointed at artifactory and they have to use old setuptools versions your company should consider not making the new version available.

@uranusjr
Copy link
Member

I guess the best thing we can do here is to explicitly state what we do and why that is the case. We can emit explicit messages during locking (either strict locking failure or a warning message) to tell the user we can’t obey those specifications because Pipenv needs them to work.

@dvzrv
Copy link
Author

dvzrv commented Jun 15, 2018

Pipenv doesn’t force anything on your virtualenv. The version of setuptools that lands there is the one you have installed globally.

I beg to differ:

pip3 list |grep setuptools
setuptools        39.0.1
pipenv run pip3 list |grep setuptools
setuptools 39.2.0

There is quite a clear automatic update happening here.

As to why we need to achieve this, is that artifactory is probably lacking the speed to deal with newer metadata and twine already making use of it, when using current versions of setuptools.

While I agree, that's something on artifactory's side to fix (will start annoying them on monday), it's also awkward to not be able to set a version for the tools you're going to use in the venv and them being force updated to the latest version automatically.

@uranusjr Thanks for opening #2365!

@techalchemy
Copy link
Member

@dvzrv the presence of an upgraded package doesn't really mean anything about pipenv, if you install something else that explicitly and strictly pins a setuptools version it will upgrade setuptools in your virtualenv. If you find evidence of pipenv engaging in this behavior please feel free to provide it, but simply showing state doesn't accomplish that.

@dvzrv
Copy link
Author

dvzrv commented Jun 16, 2018

@techalchemy I'm not sure what you're trying to achieve here. I've provided the above Pipfile and Pipfile.lock. If I remove wheel and setuptools from them (which are just silently ignored anyways), and do a fresh pipenv install for that project, while having setuptools == 39.0.1 installed on my system, setuptools will be around in the venv in version 39.2.0.
When looking at pyyaml, gitpython, gitdb2, smmap2, pip and appdirs, I don't see anything introducing version pinning for setuptools to version 39.2.0.
Therefore I'm assuming this is introduced through pipenv (unless there is something I don't see here).

If you find evidence of pipenv engaging in this behavior please feel free to provide it, but simply showing state doesn't accomplish that.

I'm unsure what else to provide to prove my point here. All logs and literally everything I provided is "state". If that's not valid, no bug reports are ever valid...

That being said: It's not constructive to disregard the collection of information by a participant to reproduce an environment, in which things do not work as intended, while at the same time not providing prove, that this is indeed intended or even documented behavior or disregarding concerns as to why a certain behavior should be changed. This only feels condescending.

I would really like to be able to assume, that with pipenv one can create reproducible environments for projects. With the current example I wonder if this can really be achieved if there's no control over certain packages and the behavior is not clearly being defined regarding those I have no control over.

@techalchemy
Copy link
Member

You misunderstand. This isn’t something pipenv does. Obviously I cannot prove a negative so you will have to prove that absent your other requirements, in a brand new environment, pipenv is upgrading setuptools. Since you are filing a bug report against pipenv you need to show that there is a bug — I don’t have your system or your environment, and while I appreciate that this is frustrating, it is not reasonable to ask us to chase down issues which we can’t reproduce and for which the only evidence is that after doing many things, an undesirable state is attained.

Surely you can understand why I am pushing back rather hard. The tenor of this issue has been that an outcome occurred and absent any other lines of inquiry and with resistance to the idea that there could possibly be any other cause, the conclusion you came to is that we are responsible for investigating and solving this problem — and that is a bit antagonistic. I get your frustration. However, we are a small team of volunteers with limited resources. If you find a bug you are welcome to report it, but unless you provide sufficient information to reproduce it and evidence that it is a problem in pipenv, we probably aren’t going to spend any resources on it. If the bug is important to you, we expect that you will at least assist us in determining whether it exists rather than assuming it does.

This project is a collaborative open source one — basically the process works better if you collaborate instead of blame.

To your last point. I already described the behavior. Go ahead and create a fresh environment by just running pipenv install six. I don’t really appreciate the passive aggressive questioning, I’d be happy to work with you if there is a bug. You need to demonstrate that by providing information about your system. If you prefer the alternative i will simply point you at the code of conduct.

@uranusjr
Copy link
Member

@dvzrv Allow me to explian. @techalchemy was trying to tell you that Pipenv does not actively enforce setuptools, pip, and wheel in the virtualenv it manages. What you provided were indirect evidence, e.g. “no-one else enforece them, so it must be Pipenv that did”. This can, however, be disproved by direct evidence, i.e. the source code of Pipenv, and as maintainers of this project, we can tell you with reasonable certainty that Pipenv does not pin setuptools to 39.2.0. Direct evidence trumps directict evidence, and in general can only be disproved by direct evidence—i.e. you need to find exactly where and how Pipenv pins setuptools.

To draw a bad analogy—my neighbour accouses my dog for stealing things from his garden yesterday. I don’t think she did. How can I prove it? I can’t, since I would have nothing to give if she didn’t take anything to begin with. My neighbour would either need to catch him doing it, or find the thing belong to him in my house. It doesn’t help if he said “well my dog didn’t take it, it must be yours”.

@dvzrv
Copy link
Author

dvzrv commented Jun 16, 2018

I don’t really appreciate the passive aggressive questioning, I’d be happy to work with you if there is a bug. You need to demonstrate that by providing information about your system. If you prefer the alternative i will simply point you at the code of conduct.

I'm unsure where you read that into any of my statements, but I can assure you, that there was no passive-aggressive intent. If you feel so, I apologize.
Funnily enough I already wanted to point out the same about the CoC, because I felt the same coming from your side.

This project is a collaborative open source one — basically the process works better if you collaborate instead of blame.

I'm fully aware of that and I also don't appreciate a passive-aggressive tone. I'm trying to provide you with information. I'm not blaming you. I'm stating what I see as output of the process I'm describing.

Let's rewind please, to help me understand. I'll use your example (pipenv install six, but my above Pipfile or just using pipenv install pip has the same outcome) in an empty folder:

Pipenv doesn’t force anything on your virtualenv. The version of setuptools that lands there is the one you have installed globally.

This is what I would have to prove wrong, correct?

1st case: macOS (sierra 10.12.6), with a brew-installed python3, brew installed pipenv. After plainly upgrading pip to >10.0, the system is left with a setuptools == 39.0.1. Doing pipenv install six leads to a venv with setuptools == 39.2.0.
2nd case: macOS (sierra 10.12.6), removed all global pip packages (from the brew-installed python3), reinstalled python3 (to have a clean environment). Added python 3.6.5 (pyenv install 3.6.5 and pyenv global 3.6.5) using pyenv only for my local user (setting PATH to $HOME/.local/bin:$HOME/.pyenv/shims:$PATH). After plainly upgrading pip to >10.0, the system is left with a setuptools == 39.0.1. Doing pipenv install six leads to a venv with setuptools == 39.2.0.

In both cases, the only "global" or "system-wide" version of setuptools is 39.0.1 (according to pip3 list), nonetheless, the one in the venv is 39.2.0 (according to pipenv run pip3 list).

This seems to be the same on Windows 10, but I can provide information on the system only early next week. I could try to reproduce this on Linux as well, but my distribution has the latest setuptools shipped and I will need to setup pyenv first, to have an older release of setuptools be the only thing seen.

What else would you need as information on the system at hand (macOS)?

This can, however, be disproved by direct evidence, i.e. the source code of Pipenv, and as maintainers of this project, we can tell you with reasonable certainty that Pipenv does not pin setuptools to 39.2.0.

@uranusjr How can the observed behavior be explained otherwise? I'm also not saying pipenv is pinning it, but it seems as if it is upgrading those packages to their latest version, although they are available in a specific version on the system (which would be contradictory to @techalchemy's earlier statement). Additionally, I couldn't find specific pinning in pip, or wheel (and also tried with having wheel==0.30.0 in my global pip3 list). I'm very clueless by now, as even "minimum venvs" with just pip, setuptools and wheel (pipenv install pip) show the same behavior (wheel and setuptools are at their latest version, although the latest version is not installed on the system).
Your analogy certainly helps in regards to minimizing the potential culprits and finding the bug or unintended behavior in question!

@techalchemy
Copy link
Member

Hmmmm... so I’m pretty sure we just spit out calls to pip sometimes, the code around that is kind of messy. Specifically, in the current releases we also make a direct call to virtualenv instead of python -m virtualenv. Can you confirm which version of virtualenv that is? I don’t think pipenv upgrades setuptools but it definitely might do something weird when creesting the env

@dvzrv
Copy link
Author

dvzrv commented Jun 17, 2018

The current version on the Mac system is 16.0.0. I assume it will be the same on Windows (will check tomorrow).

@franknarf8
Copy link

franknarf8 commented Jun 18, 2018

Hello,

Great tool, first time reporter here and long time heavy user of many other package managers (npm/yarn, nuget/paket, bower, conan, gem, old-style-pip, cargo and probably a few others, but more casually).

As I understand properly, the virtualenv creation (something like : python -m virtualenv . --python=3.6) installs some packages by default (pip, setuptools, wheel) and we don't seem to be able to override the versions of these packages directly from that command (and the python -m virtualenv . command usually always pulls the three dependencies close to latest). That is limitation we must play along with, since this is upstream-behavior.

Those three packages (an maybe others) are exceptions and we need to handle them carefully.

The behavior I would expect from Pipenv if I was to specify something like "setuptools=XYZ" in the Pipfile would be one of the following :

  1. Fail, and fail hard with an error message stating you can't specify a pinned dependency on setuptools. (Or at least, warn very loudly). This would avoid the case of trying to pin one of those exception-packages, expecting it pinned and debugging for a few hours before finally finding out virtualenv via pipenv silently installed a different version than the one you specified. It removes the illusion of control over these packages. These packages should not be pinned anyways, so it enforces the users to have clean Pipfiles
  2. Override the setuptools to the version specified in the Pipfile. e.g. with something like pipenv run install setuptools=XYZ. This way, the users of Pipenv have a standard/coherent interface across the normal-packages AND the exception-packages. They don't need to know what is happening under the hood to get their packages to the version they want.
  3. Other suggestions?

Thanks again for creating and maintaining this tool!

- Frank

@dvzrv
Copy link
Author

dvzrv commented Jun 18, 2018

What Frank said ;-)
He has the Windows 10 machine and that has latest virtualenv (16.0.0) as well.

I'd probably be most happy with 2.) but, if that will turn out to be too much of a support-nightmare 1.) (i.e. #2365) is fine, too.

In any case, it would be good to have documentation on it, so people like me don't fall under the false assumption of being able to change the versions of those tools using pipenv (with a Pipfile).

@uranusjr @techalchemy thanks for looking into it!

@techalchemy
Copy link
Member

I do just want to confirm because I am genuinely surprised -- does making a new virtualenv actually upgrade setuptools and such? I guess you might not be able to confirm this... I will get to the bottom of it though

@techalchemy techalchemy reopened this Jun 18, 2018
@franknarf8
Copy link

I'm not quite sure what happens, or how the package version of those exception-packages are set; but here are the following commands I am running in an empty folder with pipenv :

>mkdir test-pipenv & cd test-pipenv
>pip list | grep -e wheel -e setuptools
setuptools          38.5.2
wheel               0.30.0

>pipenv install
>pipenv run pip list | grep -e wheel -e setuptools
setuptools 39.2.0
wheel      0.31.1

and the same commands with a naked virtualenv.

>mkdir test-virtualenv & cd test-virtualenv
>pip list | grep -e wheel -e setuptools
setuptools          38.5.2
wheel               0.30.0

>python -m virtualenv .
>Scripts\activate.bat
>pip list | grep -e wheel -e setuptools
setuptools 39.2.0
wheel      0.31.1

The virtual environment seems to use diferent setuptools and wheel than what I have setup globally.
Creating a new virtualenv installs the latest setuptools and friends within that new virtualenv, but doesn't upgrade the globally installed ones.

Thanks again for looking into it!

@uranusjr
Copy link
Member

I may be missing things, but different versions of virtualenv can install different versions of pip, setuptools, and wheel (because it vendors them). You need to make sure you’re using the same installation of virtualenv to make a good comparison.

@franknarf8
Copy link

I have virtualenv 15.2.0

>pip list | grep virtual
virtualenv          15.2.0
virtualenv-clone    0.3.0

@franknarf8
Copy link

@uranusjr @techalchemy
Hi guys!

Any progress on this issue? Do you need any additional information?

What is your opinion on the following solution :
If setuptools (or any of the default packages, e.g. wheel) versions are pinned in the Pipfile, after creating the virtualenv, we force install the specified package in the virtual environment; something like pipenv run pip install setuptools==SPECIFIED_VERSION

That way

Thanks!

  • Frank

@jobec
Copy link

jobec commented Sep 18, 2018

Same issue here.

Trying to get Sphinx working, but when setuptools is below a certain version, it throws some errors.

In the system wide python, there's a setuptools version of 40.0 installed, but the venv pipenv creates contains an older version, incompatible with sphinx, throwing a AttributeError: '_NamespacePath' object has no attribute 'sort' error

So... back to shell scripts to wrap around pipenv...

@dvzrv
Copy link
Author

dvzrv commented Oct 5, 2018

A direct effect of this behavior can be found in #2924.
It would really be very very very good to change this!

@Diggsey
Copy link

Diggsey commented Nov 22, 2018

Yes, we suffer a lot from pipenv breakages, and I believe it's this issue which is causing unnecessary problems. Every time someone recreates their pipenv, or a CI build runs with new dependencies, and there's a pip upgrade, then pipenv inevitably breaks, and it's confusing because locking the versions down the "obvious" way does not fix it.

IMO, each version of pipenv should track which versions of pip it is known to be compatible with (eg. >= 16.0, <= 18.0): if the system pip is newer than the latest compatible version, then issue a warning that it may not work, and the command to downgrade it inside the virtualenv. If the system pip is older than the earliest compatible version, then automatically upgrade it to the minimum compatible (only inside the venv), and print out that it was upgraded.

@Overdrivr
Copy link

Not being able to lock the version of pip that is installed inside the VENV and used for installing packages is a BIG issue.

I have a pipeline that is currently stuck because latest version of pip has introduced a bug in it (pypa/pip#6163), and pipenv does not let me specify which version of pip to use, uses latest and breaks my build.

How are you supposed to achieve reproducible builds if you cannot have consistent build tools version ?

@omenos
Copy link

omenos commented Feb 27, 2019

For reference, based on @uranusjr 's comment:

https:/pypa/virtualenv/tree/master/virtualenv_support

@grazius
Copy link

grazius commented May 15, 2019

Hello
I got the same problem as @Overdrivr ...
They are no way to fix versions of setuptools, wheel when we do a pipenv install ?

mistafunk added a commit to Esri/pyprt that referenced this issue Mar 2, 2020
mistafunk added a commit to Esri/pyprt that referenced this issue Mar 3, 2020
* Remove setuptools from pipfile as it is ignored by pipenv. Also see open issue at pypa/pipenv#2364
* Removed pinned versions of build tools, we aim to keep it up-to-date with latest.
* Keeping arcgis on 1.6, cannot install newer versions on RHEL7 build agents. Not critical here as arcgis is only used for unit tests.
@katsar0v
Copy link

Hi, because of this duplicate - #4149

I wanted to ask if there is any update on this matter?

@sripberger
Copy link

sripberger commented May 21, 2020

This has suddenly become a huge problem for me.

My company has a legacy python 2.7 app that is very dated and I have no intention of trying to overhaul it or update its dependencies or anything like that. A previous engineer moved our build system to use pipenv about two years ago, so that we could just lock the dependencies and rebuild the virtual env anytime using pipenv sync. Sounded like a good idea at the time, I guess?

He didn't realize, though, that even without updating pipenv itself, the pip used to install stuff into the venv would always be the latest version of pip. Lo and behold, one of our dependencies has a post-install script that depends on something that changed in Pip 20.1, and now we can't run pipenv sync successfully.

Of course, this kind of stuff is only going to continue to get worse for us as python 2.7 is dead, and pip will understandably be dropping support for it entirely. So I imagine that pretty much all of these post install scripts will eventually break-- again, without even updating pipenv itself or anything else on the system-- unless we can pin the pip version these builds are using.

Again, I get the idea that we should get with the times and stop relying on all this old stuff, but we kind of don't have a choice right now. We need to do maintenance on this thing until I can convince my company to let us kill it forever, but because we can't do this one simple thing, I can no longer deploy it at all. It will likely to force me to find a way to either commit our .venv, or somehow find a way to consistently rebuild it using vanilla pip.

On top of that, I'm really puzzled as to how this couldn't end up being a problem inside if pipenv itself. I can't imagine that pipenv doesn't make some assumptions about how pip works that could break pipenv as pip is updated. People might expect the occasional problem when updating their build tools, but this can happen without updating pipenv at all. As is happening with us. :\

@johncylee
Copy link

johncylee commented Oct 22, 2020

I've encountered this issue recently and here is what I've found. This is on Ubuntu 20.04 and I don't know if things are similar on macOS / Windows.

$ pip3 list | grep setuptools
setuptools             45.2.0
$ dpkg -l | grep setuptools
ii  python3-setuptools                     45.2.0-1                          all          Python3 Distutils Enhancements
$ pipenv run pip3 list | grep setuptools
setuptools      44.0.0
$ locate setuptools-44.0.0
/usr/share/python-wheels/setuptools-44.0.0-py2.py3-none-any.whl
$ dpkg -S /usr/share/python-wheels/setuptools-44.0.0-py2.py3-none-any.whl
python-pip-whl: /usr/share/python-wheels/setuptools-44.0.0-py2.py3-none-any.whl

From the package description of python-pip-whl, it seems that the "wheel" version of setuptools (44.0.0) will be used in the virtualenv created by pipenv, instead of the global one (45.2.0). My workaround is to put something like this in my CI script:

pipenv sync || true  # expected to fail because of incompatible setuptools
pipenv run python -m pip install 'setuptools~=45.2.0'  # the version I need
pipenv sync  # this time it will work

Hope this helps.


Update:

Another way to do this is python3 -m pip install --user 'virtualenv~=x.y.z' to install the required version of virtualenv inside home directory. If you do not have virtualenv installed in system or home dir before running python3 -m pip install --user pipenv, it will bring in the latest compatible virtualenv as a dependency.

@stewartmiles
Copy link

stewartmiles commented Aug 18, 2022

I just stumbled across this today.

pipenv is 2022.8.17 ships with setuptools 63.2.0 which it uses to initialize venvs. However, it never upgrades setuptools due to:

pipenv/pipenv/core.py

Lines 61 to 67 in 697f1a9

BAD_PACKAGES = (
"distribute",
"pip",
"pkg-resources",
"setuptools",
"wheel",
)

pipenv/pipenv/core.py

Lines 732 to 736 in 697f1a9

deps_to_install = [
dep
for dep in deps_to_install
if not project.environment.is_satisfied(dep) and dep.name not in BAD_PACKAGES
]

This wouldn't be an much of issue for most folks due to the above code. venvs would use setuptools that ships with pipenv and that's it. However, for us it's problematic as we use some custom (much faster) logic instead of pipenv sync to install packages in our venv which reads Pipfile.lock. After running pipenv lock, Pipfile.lock points to the latest setuptools (i.e 65.1.0) rather than the one that pipenv will install (e.g 63.2.0). In our case this is a problem since we install everything in Pipfile.lock which upgrade setuptools etc.

So I think if pipenv folks really do not want to update BAD_PACKAGES, they should not be upgraded in the lock file. For example, if pipenv ships with setuptools 63.2.0 it should lock setuptools==63.2.0. For example:

$ cd $(mktemp -d)
$ pipenv shell
Creating a virtualenv for this project...
Pipfile: /tmp/tmp.Jtj9LKULhZ/Pipfile
Using /usr/bin/python3.8 (3.8.10) to create virtualenv...
⠹ Creating virtual environment...created virtual environment CPython3.8.10.final.0-64 in 165ms
  creator CPython3Posix(dest=/tmp/tmp.Jtj9LKULhZ/.venv, clear=False, no_vcs_ignore=False, global=False)
  seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=/home/stewart/.local/share/virtualenv)
    added seed packages: pip==22.2.2, setuptools==63.2.0, wheel==0.37.1
  activators BashActivator,CShellActivator,FishActivator,NushellActivator,PowerShellActivator,PythonActivator
✔ Successfully created virtual environment!
Virtualenv location: /tmp/tmp.Jtj9LKULhZ/.venv
Creating a Pipfile for this project...
Launching subshell in virtual environment...
 . /tmp/tmp.Jtj9LKULhZ/.venv/bin/activate
$ mkdir test
$ cat > test/setup.py <<EOF
from setuptools import setup

setup(
    name='test',
    install_requires=['setuptools']
)
EOF
$ cat > test/pyproject.toml <<EOF
[build-system]
requires = ["setuptools", "wheel", "packaging"]
build-backend = "setuptools.build_meta:__legacy__"
EOF
$ pipenv install -e ./test
Installing -e ./test...
✔ Installation Succeeded
Installing dependencies from Pipfile.lock (fb7610)...
  🐍   ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 1/1 — 0
$ cat Pipfile
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]
test = {editable = true, path = "./test"}

[dev-packages]

[requires]
python_version = "3.8"
$ pip list
Package    Version Editable project location
---------- ------- -------------------------
pip        22.2.2
setuptools 63.2.0
test       0.0.0   /tmp/tmp.Jtj9LKULhZ/test
wheel      0.37.1
$ cat Pipfile.lock | grep -A 7 setuptools
        "setuptools": {
            "hashes": [
                "sha256:10602cd0a6f5feab6656e9587f9075292ab777c5200f3bf00293ecd23d9f2788",
                "sha256:d2e010624c781b26ad6629a8de9832327cf853dea93894487979e55f9ad06857"
            ],
            "markers": "python_version >= '3.7'",
            "version": "==65.1.0"
        },

Here you can see, the empty test package depends upon setuptools and so pipenv lock goes and adds the latest setuptools to Pipfile.lock but doesn't upgrade the venv.

However, from scanning this bug it looks like folks would really like to use newer pip, setuptools, wheel packages so perhaps, given the guidance is to install pipenv through pipx, BAD_PACKAGES should be ditched entirely then we can all select the amazing new or potentially broken packaging tools that we want to use?

@matteius
Copy link
Member

@stewartmiles This is due to a recent change to exclude BAD_PACKAGES from the batch_install -- honestly it was a workaround because the mac os test runner started failing on a number of tests where it was trying to re-install setuptools and failing. I am revisiting the issue based on your report -- in the future you may want to open a new report since there is a lot of history in this thread to sort through. You can see the problem with the test failure is actually that pipenv is having trouble upgrading setuptools from the lockfile, because it seems the old setuptools get moved out of the way, then it tries to use setuptools to install but cannot find it: https:/pypa/pipenv/runs/7908655417?check_suite_focus=true

@stewartmiles
Copy link

@matteius there are a huge number of issues in this repo so I felt bad adding to the list and did my best to find the most relevant issue. Thanks for letting me know this is a recent issue.

w.r.t the failing test, I took a look at the Ubuntu logs at https:/pypa/pipenv/runs/7908654820?check_suite_focus=true

It's interesting that pip depends upon distutils which has now been vendored into setuptools and should soon be gone (I stumbled across pypa/pip#10647).

I'm confused about how pipenv is tickling this though since pip needs to load distutils modules to install or uninstall and therefore they should be resident in memory as execution continues.

Using pip directly the setuptools upgrade works fine:

$ pipenv --python 3.8 && pipenv run pip install setuptools==63.4.1 && echo 'setuptools==65.1.0; --hash=sha256:10602cd0a6f5feab6656e9587f9075292ab777c5200f3bf00293ecd23d9f2788 --hash=sha256:d2e010624c781b26ad6629a8de9832327cf853dea93894487979e55f9ad06857' > setuptools_req.txt && pipenv run pip install -r setuptools_req.txt
Creating a virtualenv for this project...
Pipfile: /home/stewart/src/agentic/service/Pipfile
Using /usr/bin/python3.8 (3.8.10) to create virtualenv...
⠹ Creating virtual environment...created virtual environment CPython3.8.10.final.0-64 in 166ms
  creator CPython3Posix(dest=/home/stewart/src/agentic/service/.venv, clear=False, no_vcs_ignore=False, global=False)
  seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=/home/stewart/.local/share/virtualenv)
    added seed packages: pip==22.2.2, setuptools==63.2.0, wheel==0.37.1
  activators BashActivator,CShellActivator,FishActivator,NushellActivator,PowerShellActivator,PythonActivator
✔ Successfully created virtual environment!
Virtualenv location: /home/stewart/src/agentic/service/.venv
Loading .env environment variables...
Looking in links: /home/stewart/src/agentic/service/wheels
Collecting setuptools==63.4.1
  Using cached setuptools-63.4.1-py3-none-any.whl (1.2 MB)
Installing collected packages: setuptools
  Attempting uninstall: setuptools
    Found existing installation: setuptools 63.2.0
    Uninstalling setuptools-63.2.0:
      Successfully uninstalled setuptools-63.2.0
Successfully installed setuptools-63.4.1
Loading .env environment variables...
Looking in links: /home/stewart/src/agentic/service/wheels
Collecting setuptools==65.1.0
  Using cached setuptools-65.1.0-py3-none-any.whl (1.2 MB)
Installing collected packages: setuptools
  Attempting uninstall: setuptools
    Found existing installation: setuptools 63.4.1
    Uninstalling setuptools-63.4.1:
      Successfully uninstalled setuptools-63.4.1
Successfully installed setuptools-65.1.0

When using pipenv install, we see the failure:

$ rm -rf .venv; pipenv --python 3.8 && pipenv install setuptools==65.1.0
Creating a virtualenv for this project...
Pipfile: /tmp/tmp.9ZqA1EKQ0E/Pipfile
Using /usr/bin/python3.8 (3.8.10) to create virtualenv...

⠋ Creating virtual environment...�
⠙ Creating virtual environment...�
⠹ Creating virtual environment...�
⠸ Creating virtual environment...created virtual environment CPython3.8.10.final.0-64 in 172ms
  creator CPython3Posix(dest=/tmp/tmp.9ZqA1EKQ0E/.venv, clear=False, no_vcs_ignore=False, global=False)
  seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=/home/stewart/.local/share/virtualenv)
    added seed packages: pip==22.2.2, setuptools==63.2.0, wheel==0.37.1
  activators BashActivator,CShellActivator,FishActivator,NushellActivator,PowerShellActivator,PythonActivator

�✔ Successfully created virtual environment! 
Virtualenv location: /tmp/tmp.9ZqA1EKQ0E/.venv
Installing setuptools==65.1.0...

⠋ Installing...�
⠙ Installing setuptools...�
⠹ Installing setuptools...�
⠸ Installing setuptools...�
⠼ Installing setuptools...�
⠴ Installing setuptools...�
⠦ Installing setuptools...�
⠧ Installing setuptools...�
⠇ Installing setuptools...�
⠏ Installing setuptools...�
⠋ Installing setuptools...�
⠙ Installing setuptools...�
⠹ Installing setuptools...�
⠸ Installing setuptools...
Error:  An error occurred while installing setuptools==65.1.0!

Error text: Collecting setuptools==65.1.0
  Using cached setuptools-65.1.0-py3-none-any.whl (1.2 MB)
Installing collected packages: setuptools
  Attempting uninstall: setuptools
    Found existing installation: setuptools 63.2.0
    Uninstalling setuptools-63.2.0:
      Successfully uninstalled setuptools-63.2.0
  Rolling back uninstall of setuptools
  Moving to /tmp/tmp.9ZqA1EKQ0E/.venv/lib/python3.8/site-packages/_distutils_hack/
   from /tmp/tmp.9ZqA1EKQ0E/.venv/lib/python3.8/site-packages/~distutils_hack
  Moving to /tmp/tmp.9ZqA1EKQ0E/.venv/lib/python3.8/site-packages/distutils-precedence.pth
   from /tmp/pip-uninstall-rjvx3odd/distutils-precedence.pth
  Moving to /tmp/tmp.9ZqA1EKQ0E/.venv/lib/python3.8/site-packages/pkg_resources/
   from /tmp/tmp.9ZqA1EKQ0E/.venv/lib/python3.8/site-packages/~kg_resources
  Moving to /tmp/tmp.9ZqA1EKQ0E/.venv/lib/python3.8/site-packages/setuptools-63.2.0.dist-info/
   from /tmp/tmp.9ZqA1EKQ0E/.venv/lib/python3.8/site-packages/~etuptools-63.2.0.dist-info
  Moving to /tmp/tmp.9ZqA1EKQ0E/.venv/lib/python3.8/site-packages/setuptools-63.2.0.virtualenv
   from /tmp/pip-uninstall-rjvx3odd/setuptools-63.2.0.virtualenv
  Moving to /tmp/tmp.9ZqA1EKQ0E/.venv/lib/python3.8/site-packages/setuptools/
   from /tmp/tmp.9ZqA1EKQ0E/.venv/lib/python3.8/site-packages/~etuptools


ERROR: Exception:
Traceback (most recent call last):
  File "/home/stewart/.local/pipx/venvs/pipenv/lib/python3.8/site-packages/pipenv/patched/pip/_internal/cli/base_command.py", line 167, in exc_logging_wrapper
    status = run_func(*args)
  File "/home/stewart/.local/pipx/venvs/pipenv/lib/python3.8/site-packages/pipenv/patched/pip/_internal/cli/req_command.py", line 247, in wrapper
    return func(self, options, args)
  File "/home/stewart/.local/pipx/venvs/pipenv/lib/python3.8/site-packages/pipenv/patched/pip/_internal/commands/install.py", line 461, in run
    installed = install_given_reqs(
  File "/home/stewart/.local/pipx/venvs/pipenv/lib/python3.8/site-packages/pipenv/patched/pip/_internal/req/__init__.py", line 73, in install_given_reqs
    requirement.install(
  File "/home/stewart/.local/pipx/venvs/pipenv/lib/python3.8/site-packages/pipenv/patched/pip/_internal/req/req_install.py", line 753, in install
    scheme = get_scheme(
  File "/home/stewart/.local/pipx/venvs/pipenv/lib/python3.8/site-packages/pipenv/patched/pip/_internal/locations/__init__.py", line 250, in get_scheme
    old = _distutils.get_scheme(
  File "/home/stewart/.local/pipx/venvs/pipenv/lib/python3.8/site-packages/pipenv/patched/pip/_internal/locations/_distutils.py", line 141, in get_scheme
    scheme = distutils_scheme(dist_name, user, home, root, isolated, prefix)
  File "/home/stewart/.local/pipx/venvs/pipenv/lib/python3.8/site-packages/pipenv/patched/pip/_internal/locations/_distutils.py", line 66, in distutils_scheme
    obj = d.get_command_obj("install", create=True)
  File "/tmp/tmp.9ZqA1EKQ0E/.venv/lib/python3.8/site-packages/setuptools/_distutils/dist.py", line 859, in get_command_obj
    klass = self.get_command_class(command)
  File "/tmp/tmp.9ZqA1EKQ0E/.venv/lib/python3.8/site-packages/setuptools/dist.py", line 954, in get_command_class
    self.cmdclass[command] = cmdclass = ep.load()
  File "/tmp/tmp.9ZqA1EKQ0E/.venv/lib/python3.8/site-packages/setuptools/_vendor/importlib_metadata/__init__.py", line 194, in load
    module = import_module(match.group('module'))
  File "/usr/lib/python3.8/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 973, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'setuptools.command.install'

�✘ Installation Failed 

I think the stack trace here provides a clue to what's going on. The stack is pointing at the pip install in my pipx managed venv for pipenv (i.e /home/stewart/.local/pipx/venvs/pipenv) not the one in the newly created in the temporary directory (i.e /tmp/tmp.9ZqA1EKQ0E/.venv). So we've got a case of crossing the venvs, i.e we're trying use python in the pipenv managed venv (under /tmp/tmp.9ZqA1EKQ0E/.venv) where pip is installed in a separate venv (under /home/stewart/.local/pipx/venvs/pipenv).

Changing:

https:/pypa/pipenv/blob/main/pipenv/core.py#L1528-L1532

to:

pip_command = [
    project_python(project, system=allow_global),
    "-m", "pip",
    "install",
]

runs pip installed in the venv. Using this code we end up with something that works:

$ rm -rf .venv; pipenv --python 3.8 && pipenv install setuptools==65.1.0
Creating a virtualenv for this project...
Pipfile: /tmp/tmp.9ZqA1EKQ0E/Pipfile
Using /usr/bin/python3.8 (3.8.10) to create virtualenv...
⠹ Creating virtual environment...created virtual environment CPython3.8.10.final.0-64 in 163ms
  creator CPython3Posix(dest=/tmp/tmp.9ZqA1EKQ0E/.venv, clear=False, no_vcs_ignore=False, global=False)
  seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=/home/stewart/.local/share/virtualenv)
    added seed packages: pip==22.2.2, setuptools==63.2.0, wheel==0.37.1
  activators BashActivator,CShellActivator,FishActivator,NushellActivator,PowerShellActivator,PythonActivator
                                                                                                   ✔ Successfully created virtual environment!
Virtualenv location: /tmp/tmp.9ZqA1EKQ0E/.venv
Installing setuptools==65.1.0...
Adding setuptools to Pipfile's [packages]...                                                       ✔ Installation Succeeded
Pipfile.lock not found, creating...
Locking [packages] dependencies...
 Locking...Building requirements...
⠙ Locking..✔ Success! ...
Locking [dev-packages] dependencies...
Updated Pipfile.lock (8a817f)!
Installing dependencies from Pipfile.lock (8a817f)...
  🐍   ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 0/0 — 00

So this leaves me with questions:

  • Why is pip patched in pipenv. What's wrong with the standard version?
  • Why not use pip within the venv everywhere i.e invoke with python -m pip instead of what it's doing now?

@matteius
Copy link
Member

matteius commented Aug 19, 2022

Why is pip patched in pipenv. What's wrong with the standard version?

@stewartmiles There are a few patches we support of pip, include some for resolver specifiers, and also an important one is for index restricted packages to prevent package confusion attacks by requiring that every package required calls out a specific index, or uses only the default.

Why not use pip within the venv everywhere i.e invoke with python -m pip instead of what it's doing now?

There are a few reasons. Pipenv has had a split between using the vendor'd pip and the user pip for a while and it created its own array of problems. One is because there have been at least a handful or more issues that related to inconsistent behaviors between different versions of pip the user might have installed and what pipenv expects. Plus we rely heavily on pip internals and already vendor in the latest version of pip or typically aren't far behind it, so we can have consistency in what is expected to be executed, and the same patches to pip would apply. I've seen some other issue reports gets closed out as a result of this change, and it allowed us to not explicitly require pip be installed to have pipenv installed.

I would like to figure out how to resolve this without reverting back to requiring a user/system pip and re-igniting those other types of issues. I think there are other pipenv bugs related to which python is utilized, so maybe the answer lies in project_python(project, system=allow_global)? I will have to re-read what you said about the crossing the venvs, because I am not quite sure why we would be referencing pip from a different virtualenv the other way. FWIW the CI does not use pipx

Also odd is that python 3.10 doesn't have this issue, but < 3.10 struggles on this setuptools upgrade.

@matteius
Copy link
Member

@stewartmiles thanks to your comment I now have the PR passing for allowing installation of the BAD__PACKAGES again. Waiting on it to get reviewed, but in my local testing it worked and you are welcome to try it out. #5275

@matteius
Copy link
Member

This is fixed in pipenv==2022.8.19

@stewartmiles
Copy link

@matteius great news that you're able to get this working with my minimal example. I'll give it a try.

Hopefully you noticed that my patch ended up using pip in the venv - which is the pipenv patched pip - not the system pip. Since pip can be upgraded I guess this is brittle w.r.t pipenv's pip internal usage. Though using the patched pip is brittle as pip such an active project, it makes me wonder whether pipenv maintainers have considered / tried to upstream pip patches rather than carrying them across each release?

@matteius
Copy link
Member

@stewartmiles -- I cannot say that I agree that using the vendor'd patched pip is brittle -- it creates runtime consistency across users of pipenv and reduces a subset of issues that I have seen. I would argue that trying to rely on the system pip has its own brittleness to it, especially by where pipenv imports pip internals which pretty much means it has always had a vendor'd version of pip since the move away from pip-tools. I recently was able to rename that vendoring from notpip to pip because it was pretty misleading to many newcomers to the project, myself included, and it is very much is in-fact pip. We have been keeping pip vendoring updated with the latest pypi releases of pip as well.

it makes me wonder whether pipenv maintainers have considered / tried to upstream pip patches rather than carrying them across each release.

Yes but upstream is complicated by the fact we use pip internals and the pip maintainers are not interested in patches that affect pip internals without having a direct use case by the pip CLI. For more insight review the discussion on the PR where I tried to patch pip internals for the index restrictions, a patch that pipenv actively maintains: pypa/pip#10964

The set of patches is minimal, documented and maintained as patch files in pipenv: https:/pypa/pipenv/tree/main/tasks/vendoring/patches/patched

@stewartmiles
Copy link

@matteius oh I agree with vendoring pip into pipenv, that makes a heap of sense to me. You install pipenv and venvs are seeded with a consistent version of pip that works consistently without dealing with various patched versions of pip that are shipped by OS vendors. The main thing that worried me a bit was using pip embedded in pipenv to manage a venv rather than using the version of pip - chosen by the user - within the venv. I guess if you have a set of patches that apply consistently without much maintenance, such that each pipenv release can integrate a new version of pip and pipenv doesn't upgrade pip in the venv (since users run pip without pipenv to test things out), I guess that's just fine.

I had a glance at the patches and I'm surprised some of these can't be upstreamed e.g in https:/pypa/pipenv/blob/main/tasks/vendoring/patches/patched/pip22.patch :

  • Ignore compatibility: Seems like something handy to propagate through the CLI or an environment variable back door.
  • Setting python executable: Is a bit niche since I'm guessing this is to use pip from one Python environment to install packages into a different a venv. However, I could see how other venv managers (e.g Poetry) may want something similar.

Anyway, I get where you're coming from OSS is definitely hard 😉 Thanks again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Needs More Information This issue does not provide enough information to take further action.
Projects
None yet
Development

Successfully merging a pull request may close this issue.