pipenv icon indicating copy to clipboard operation
pipenv copied to clipboard

Installing bad package name removes version specifiers from Pipfile causing lock failures

Open edwinjosegeorge opened this issue 2 years ago • 13 comments

Issue description

Unable to lock using pipenv==2023.8.23 while pipenv==2023.8.21 can. The latest version reports mismatch in sub-dependency but upon inspection, the resolution is actually possible.

Expected result

Lock to succeed

Actual result

> pipenv lock
Locking [packages] dependencies...
Building requirements...
Resolving dependencies...
✘ Locking Failed!
⠦ Locking...
CRITICAL:pipenv.patched.pip._internal.resolution.resolvelib.factory:Cannot install -r /var/folders/pm/7grpkr192dq50xdn86kw8clh0000gp/T/pipenv-1ka_j20u-requirements/pipenv-xf2cewnc-constraints.txt (line 3) and pydantic[email] because these package versions have conflicting dependencies.
INFO:pipenv.patched.pip._internal.resolution.resolvelib.factory:
The conflict is caused by:
    The user requested pydantic[email]
    private-lib 0.3.19 depends on pydantic[email]<2.0.0 and >=1.10.4
    The user requested pydantic[email]
    private-lib 0.3.18 depends on pydantic[email]<2.0.0 and >=1.10.4
    The user requested pydantic[email]
    private-lib 0.3.17 depends on pydantic[email]<2.0.0 and >=1.10.4
    The user requested pydantic[email]
    private-lib 0.3.16 depends on pydantic[email]<2.0.0 and >=1.10.4
    The user requested pydantic[email]
    private-lib 0.3.15 depends on pydantic[email]<2.0.0 and >=1.10.4
    The user requested pydantic[email]
    private-lib 0.3.14 depends on pydantic[email]<2.0.0 and >=1.10.4
    The user requested pydantic[email]
    private-lib 0.3.13 depends on pydantic[email]<2.0.0 and >=1.10.4
To fix this you could try to:
1. loosen the range of package versions you've specified
2. remove package versions to allow pip attempt to solve the dependency conflict
[ResolutionFailure]:   File "/opt/homebrew/Cellar/pipenv/2023.8.23/libexec/lib/python3.11/site-packages/pipenv/resolver.py", line 647, in _main
[ResolutionFailure]:       resolve_packages(
[ResolutionFailure]:   File "/opt/homebrew/Cellar/pipenv/2023.8.23/libexec/lib/python3.11/site-packages/pipenv/resolver.py", line 614, in resolve_packages
[ResolutionFailure]:       results, resolver = resolve(
[ResolutionFailure]:       ^^^^^^^^
[ResolutionFailure]:   File "/opt/homebrew/Cellar/pipenv/2023.8.23/libexec/lib/python3.11/site-packages/pipenv/resolver.py", line 594, in resolve
[ResolutionFailure]:       return resolve_deps(
[ResolutionFailure]:       ^^^^^^^^^^^^^
[ResolutionFailure]:   File "/opt/homebrew/Cellar/pipenv/2023.8.23/libexec/lib/python3.11/site-packages/pipenv/utils/resolver.py", line 848, in resolve_deps
[ResolutionFailure]:       results, hashes, internal_resolver = actually_resolve_deps(
[ResolutionFailure]:       ^^^^^^^^^^^^^^^^^^^^^^
[ResolutionFailure]:   File "/opt/homebrew/Cellar/pipenv/2023.8.23/libexec/lib/python3.11/site-packages/pipenv/utils/resolver.py", line 621, in actually_resolve_deps
[ResolutionFailure]:       resolver.resolve()
[ResolutionFailure]:   File "/opt/homebrew/Cellar/pipenv/2023.8.23/libexec/lib/python3.11/site-packages/pipenv/utils/resolver.py", line 447, in resolve
[ResolutionFailure]:       raise ResolutionFailure(message=str(e))
[pipenv.exceptions.ResolutionFailure]: Warning: Your dependencies could not be resolved. You likely have a mismatch in your sub-dependencies.
  You can use $ pipenv run pip install <requirement_name> to bypass this mechanism, then run $ pipenv graph to inspect the versions actually installed in the virtualenv.
  Hint: try $ pipenv lock --pre if it is a pre-release dependency.
ERROR: ResolutionImpossible: for help visit https://pip.pypa.io/en/latest/topics/dependency-resolution/#dealing-with-dependency-conflicts

Traceback (most recent call last):
  File "/opt/homebrew/Cellar/pipenv/2023.8.23/libexec/bin/pipenv", line 8, in <module>
    sys.exit(cli())
             ^^^^^
  File "/opt/homebrew/Cellar/pipenv/2023.8.23/libexec/lib/python3.11/site-packages/pipenv/vendor/click/core.py", line 1130, in __call__
    return self.main(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/pipenv/2023.8.23/libexec/lib/python3.11/site-packages/pipenv/cli/options.py", line 58, in main
    return super().main(*args, **kwargs, windows_expand_args=False)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/pipenv/2023.8.23/libexec/lib/python3.11/site-packages/pipenv/vendor/click/core.py", line 1055, in main
    rv = self.invoke(ctx)
         ^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/pipenv/2023.8.23/libexec/lib/python3.11/site-packages/pipenv/vendor/click/core.py", line 1657, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/pipenv/2023.8.23/libexec/lib/python3.11/site-packages/pipenv/vendor/click/core.py", line 1404, in invoke
    return ctx.invoke(self.callback, **ctx.params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/pipenv/2023.8.23/libexec/lib/python3.11/site-packages/pipenv/vendor/click/core.py", line 760, in invoke
    return __callback(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/pipenv/2023.8.23/libexec/lib/python3.11/site-packages/pipenv/vendor/click/decorators.py", line 84, in new_func
    return ctx.invoke(f, obj, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/pipenv/2023.8.23/libexec/lib/python3.11/site-packages/pipenv/vendor/click/core.py", line 760, in invoke
    return __callback(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/pipenv/2023.8.23/libexec/lib/python3.11/site-packages/pipenv/vendor/click/decorators.py", line 26, in new_func
    return f(get_current_context(), *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/pipenv/2023.8.23/libexec/lib/python3.11/site-packages/pipenv/cli/command.py", line 340, in lock
    do_lock(
  File "/opt/homebrew/Cellar/pipenv/2023.8.23/libexec/lib/python3.11/site-packages/pipenv/routines/lock.py", line 65, in do_lock
    venv_resolve_deps(
  File "/opt/homebrew/Cellar/pipenv/2023.8.23/libexec/lib/python3.11/site-packages/pipenv/utils/resolver.py", line 789, in venv_resolve_deps
    c = resolve(cmd, st, project=project)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/pipenv/2023.8.23/libexec/lib/python3.11/site-packages/pipenv/utils/resolver.py", line 658, in resolve
    raise RuntimeError("Failed to lock Pipfile.lock!")
RuntimeError: Failed to lock Pipfile.lock!

Steps to replicate

My Pipfile

[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[[source]]
url = "${PRIVATE_URL}"
verify_ssl = true
name = "myprivatelib"

[packages]
private-lib = {version = "*", index = "myprivatelib"}
pydantic = {extras = ["email"]}

[dev-packages]

[requires]
python_version = "3.11"

remove the old lock file

rm Pipfile.lock

Create new lock

pipenv lock

This command fails for pipenv==2023.8.23 but succeeds for pipenv=2023.8.21 as the later installs pydantic==1.10.12

edwinjosegeorge avatar Aug 25 '23 05:08 edwinjosegeorge

Is it because you are missing a version specifier on pydantic?

Nothing else really stands out to me about it: https://github.com/pypa/pipenv/compare/v2023.8.21...v2023.8.23

matteius avatar Aug 25 '23 07:08 matteius

Does the new version check for the "version" tag in pipfile? Somehow the previous version is able to achieve locking without this constraint. When I add version=* for pydantic, I am able to build the lock.

The error seems misleading as pipenv should be iterating the version of pydantic and not the private-repo

edwinjosegeorge avatar Aug 25 '23 17:08 edwinjosegeorge

I was under the assumption in the refactor away from requirementslib that if the pipfile entry is a string, its likely a version specifier (but learned it could be a vcs string) and then I thought if it was a dictionary there would always be a version key for a named requirement. I just checked out to 2023.7.23 which was before that refactor was merged, the basic install command does add a version key:

$ pipenv install pydantic["email"]
Creating a virtualenv for this project...
Pipfile: C:\Users\matte\Projects\pipenv-triage\pipenv-5865\Pipfile
Using default python from C:\Users\matte\AppData\Local\Programs\Python\Python311\python.exe (3.11.2) to create virtualenv...
[   =] Creating virtual environment...created virtual environment CPython3.11.2.final.0-64 in 3210ms
  creator CPython3Windows(dest=C:\c\users\matte\.virtualenvs\pipenv-5865-uw0NJOV8, clear=False, no_vcs_ignore=False, global=False)
  seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=C:\Users\matte\AppData\Local\pypa\virtualenv)
    added seed packages: pip==23.2.1, setuptools==68.0.0, wheel==0.41.1
  activators BashActivator,BatchActivator,FishActivator,NushellActivator,PowerShellActivator,PythonActivator

Successfully created virtual environment!
Virtualenv location: C:\c\Users\matte\.virtualenvs\pipenv-5865-uw0NJOV8
Creating a Pipfile for this project...
Installing pydantic[email]...
Resolving pydantic...
Adding pydantic to Pipfile's [packages] ...
Installation Succeeded
Pipfile.lock not found, creating...
Locking [packages] dependencies...
Building requirements...
Resolving dependencies...
Resolving dependencies...
Success!
Locking [dev-packages] dependencies...
Updated Pipfile.lock (c85e765bf1ae1df8dd2ada36ab6adccb8c888756749bbf045a47708346853ede)!
Installing dependencies from Pipfile.lock (853ede)...
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.

matte@LAPTOP-N5VSGIBD MINGW64 ~/Projects/pipenv-triage/pipenv-5865
$ cat Pipfile
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]
pydantic = {version = "*", extras = ["email"]}

[dev-packages]

[requires]
python_version = "3.9"

While on the one hand we want to be backwards compatible, I think this is a case where it is better if we move forward with requiring the version specifier and not inferring you mean star specifier. I think then the enhancement would be based around Pipfile validation before entering into a lock phase. I think that was something you were interested in looking at one point @oz123 ?

matteius avatar Aug 25 '23 19:08 matteius

It seems like we should reinclude Cerberus in our vendor. That pipfile without version specificier should trigger an exception.

oz123 avatar Aug 25 '23 20:08 oz123

we should reinclude Cerberus in our vendor

I'd be in favor of consider it vs a vanilla data-class solution that does some validations -- its such an old library that I think if we can avoid it we will be better off.

matteius avatar Aug 26 '23 12:08 matteius

Re-adding Cerberus is only temporary until we do a rewrite with dataclasses. Also, Cerberus is already an optional dependancy of plette. And while it's old - it's stable and has a concise API. I'm kind of sorry I removed it prematurely from our vendor library.

oz123 avatar Aug 26 '23 12:08 oz123

I have a couple of doubts here.... I am finding some odd behaviour

Installing a package that does not exist??

> pipenv install some_random_package          
Installing some_random_package...
Resolving some_random_package...
Added some-random-package to Pipfile's [packages] ...
✔ Installation Succeeded
Pipfile.lock (7a3e87) out of date, updating to (ed4d91)...
Locking [packages] dependencies...
Building requirements...
Resolving dependencies...
✘ Locking Failed!
⠇ Locking...
CRITICAL:pipenv.patched.pip._internal.resolution.resolvelib.factory:Could not find a version that satisfies the requirement some-random-package (from versions: none)
[ResolutionFailure]:   File "/opt/homebrew/Cellar/pipenv/2023.8.23/libexec/lib/python3.11/site-packages/pipenv/resolver.py", line 647, in _main
[ResolutionFailure]:       resolve_packages(
[ResolutionFailure]:   File "/opt/homebrew/Cellar/pipenv/2023.8.23/libexec/lib/python3.11/site-packages/pipenv/resolver.py", line 614, in resolve_packages
[ResolutionFailure]:       results, resolver = resolve(
[ResolutionFailure]:       ^^^^^^^^
[ResolutionFailure]:   File "/opt/homebrew/Cellar/pipenv/2023.8.23/libexec/lib/python3.11/site-packages/pipenv/resolver.py", line 594, in resolve
[ResolutionFailure]:       return resolve_deps(
[ResolutionFailure]:       ^^^^^^^^^^^^^
[ResolutionFailure]:   File "/opt/homebrew/Cellar/pipenv/2023.8.23/libexec/lib/python3.11/site-packages/pipenv/utils/resolver.py", line 848, in resolve_deps
[ResolutionFailure]:       results, hashes, internal_resolver = actually_resolve_deps(
[ResolutionFailure]:       ^^^^^^^^^^^^^^^^^^^^^^
[ResolutionFailure]:   File "/opt/homebrew/Cellar/pipenv/2023.8.23/libexec/lib/python3.11/site-packages/pipenv/utils/resolver.py", line 621, in actually_resolve_deps
[ResolutionFailure]:       resolver.resolve()
[ResolutionFailure]:   File "/opt/homebrew/Cellar/pipenv/2023.8.23/libexec/lib/python3.11/site-packages/pipenv/utils/resolver.py", line 447, in resolve
[ResolutionFailure]:       raise ResolutionFailure(message=str(e))
[pipenv.exceptions.ResolutionFailure]: Warning: Your dependencies could not be resolved. You likely have a mismatch in your sub-dependencies.
  You can use $ pipenv run pip install <requirement_name> to bypass this mechanism, then run $ pipenv graph to inspect the versions actually installed in the virtualenv.
  Hint: try $ pipenv lock --pre if it is a pre-release dependency.
ERROR: No matching distribution found for some-random-package

Traceback (most recent call last):
  File "/opt/homebrew/Cellar/pipenv/2023.8.23/libexec/bin/pipenv", line 8, in <module>
    sys.exit(cli())
             ^^^^^
  File "/opt/homebrew/Cellar/pipenv/2023.8.23/libexec/lib/python3.11/site-packages/pipenv/vendor/click/core.py", line 1130, in __call__
    return self.main(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/pipenv/2023.8.23/libexec/lib/python3.11/site-packages/pipenv/cli/options.py", line 58, in main
    return super().main(*args, **kwargs, windows_expand_args=False)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/pipenv/2023.8.23/libexec/lib/python3.11/site-packages/pipenv/vendor/click/core.py", line 1055, in main
    rv = self.invoke(ctx)
         ^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/pipenv/2023.8.23/libexec/lib/python3.11/site-packages/pipenv/vendor/click/core.py", line 1657, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/pipenv/2023.8.23/libexec/lib/python3.11/site-packages/pipenv/vendor/click/core.py", line 1404, in invoke
    return ctx.invoke(self.callback, **ctx.params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/pipenv/2023.8.23/libexec/lib/python3.11/site-packages/pipenv/vendor/click/core.py", line 760, in invoke
    return __callback(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/pipenv/2023.8.23/libexec/lib/python3.11/site-packages/pipenv/vendor/click/decorators.py", line 84, in new_func
    return ctx.invoke(f, obj, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/pipenv/2023.8.23/libexec/lib/python3.11/site-packages/pipenv/vendor/click/core.py", line 760, in invoke
    return __callback(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/pipenv/2023.8.23/libexec/lib/python3.11/site-packages/pipenv/cli/command.py", line 209, in install
    do_install(
  File "/opt/homebrew/Cellar/pipenv/2023.8.23/libexec/lib/python3.11/site-packages/pipenv/routines/install.py", line 297, in do_install
    raise e
  File "/opt/homebrew/Cellar/pipenv/2023.8.23/libexec/lib/python3.11/site-packages/pipenv/routines/install.py", line 281, in do_install
    do_init(
  File "/opt/homebrew/Cellar/pipenv/2023.8.23/libexec/lib/python3.11/site-packages/pipenv/routines/install.py", line 648, in do_init
    do_lock(
  File "/opt/homebrew/Cellar/pipenv/2023.8.23/libexec/lib/python3.11/site-packages/pipenv/routines/lock.py", line 65, in do_lock
    venv_resolve_deps(
  File "/opt/homebrew/Cellar/pipenv/2023.8.23/libexec/lib/python3.11/site-packages/pipenv/utils/resolver.py", line 789, in venv_resolve_deps
    c = resolve(cmd, st, project=project)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/pipenv/2023.8.23/libexec/lib/python3.11/site-packages/pipenv/utils/resolver.py", line 658, in resolve
    raise RuntimeError("Failed to lock Pipfile.lock!")
RuntimeError: Failed to lock Pipfile.lock!

The command have failed as expected, but what does Added some-random-package to Pipfile's [packages] ...✔ Installation Succeeded means??

Automatically removes the version specifiers in pipfile

This is my pipfile initially

[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]
pydantic = {extras = ["email"], version = "<2.0"}

[dev-packages]

[requires]
python_version = "3.11"

Lets say I made some typo and wrote the following

pipenv install --dev some_random_package

The output is same as the first one, installation have failed, BUT now pipfile is updated to following

[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]
pydantic = {extras = ["email"] }

[dev-packages]

[requires]
python_version = "3.11"

pydantic have lost its version tag. In the first command i ran, the neither the pipfile, nor the lock file was updated

It was this change that caused me to face the issue I raised, and just adding the version in pydantic helped to lock new package that was being installed

edwinjosegeorge avatar Aug 28 '23 10:08 edwinjosegeorge

@edwinjosegeorge Are you saying trying to install a non existent package that fails is removing the version specifier for an unrelated Pipfile entry? 🤔

matteius avatar Aug 28 '23 10:08 matteius

Yep. There is no such package

  1. I do get a message "Installation Succeeded"
  2. It removes the version specifiers in pipfile ( when used with pipenv install --dev )

edwinjosegeorge avatar Aug 28 '23 10:08 edwinjosegeorge

That is really bizarre -- I just confirmed what you are saying -- the interesting thing is the version specifiers were left alone in dev group, but in the packages it was stripped from the dictionary.

matteius avatar Aug 28 '23 11:08 matteius

I think any failed install causes this behavior, not just nonexistent packages, FYI. I'm running into the problem like this:

> pipenv --version
pipenv, version 2023.8.23
> pipenv install invenio-app-rdm[opensearch2,postgresql]==11.0.4 # succeeds, version in Pipfile
> pipenv install invenio-saml # fails with a build error on my MacOS
> grep invenio-app-rdm Pipfile
invenio-app-rdm = {extras = ["postgresql", "opensearch2"] }

phette23 avatar Sep 18 '23 23:09 phette23

I believe this has been fixed in 2024.3.0 or recent version, hard to confirm, though I haven't seen it happen.

matteius avatar Oct 30 '24 03:10 matteius

I can't reproduce it anymore in my tests, trying

> pipenv --version
pipenv, version 2024.3.0
> pipenv install requests==2.32.2
> pipenv install cchardet==2.1.7 # this fails for me
> grep requests Pipfile
requests = "==2.32.2"

phette23 avatar Oct 30 '24 21:10 phette23