Guard installed packages from upgrade when installing new packages with pip - python

Imagine I have two packages foo and bar where foo is a dependency of bar. foo is already installed and I now want to install bar with pip. Is it possible to do that without upgrading foo? In particular I want to install the latest version of bar that is satisfied with the installed version of foo.
From pip help install
--upgrade-strategy <upgrade_strategy>
Determines how dependency upgrading should be handled
[default: only-if-needed]. "eager" - dependencies are
upgraded regardless of whether the currently installed
version satisfies the requirements of the upgraded
package(s). "only-if-needed" - are upgraded only when
they do not satisfy the requirements of the upgraded
package(s).
As far as I see this only covers the cases "always update" and "only update if needed", but not "never update" as I need it.

pip install bar (no upgrade flags at all) should do what you want. pip should pick the currently-installed foo unless bar explicitly says that version is not compatible. The new (2020) resolver is also capable of finding a bar version that can work with the currently-installed foo version, by automatically trying available versions one by one (called backtracking), and installing that. The 2020 resolver is an opt-in feature in pip 20.2, available via --use-feature=2020-resolver, and is schedule to become the default in 20.3 (planeed release in October 2020).
The caveat, however, is that Python packaging does not provide a way to discover version conflicts without downloading the package (sometimes even building from source).1 This would be a problem if the package bar is costly to download (e.g. tensorflow) and/or build (e.g. you’re installing numpy on less-supported platforms like Alpine Linux). In that case, the only choice would be to specify the version manually, since pip has no way to know what version of bar can be used, unless you tell it explicitly, without trying to download various versions of it.

Related

Pip package version conflicts despite seemingly matching ranges

When using pip install -r requirements.txt, I get ERROR: Cannot install -r requirements.txt (line 3), [...] because these package versions have conflicting dependencies..
And further:
The conflict is caused by:
tensorflow 2.11.0 depends on protobuf<3.20 and >=3.9.2
tensorboard 2.11.0 depends on protobuf<4 and >=3.9.2
wandb 0.13.5 depends on protobuf!=4.0.*, !=4.21.0, <5 and >=3.12.0
I don't see any conflicts in these ranges - every version in [3.12.0, 3.20) should be fine. Can someone explain the problem?
Update: As a workaround, I removed all version restrictions and only specified the names of the libraries in the requirements.txt file. Now it works. But I still don't see a problem with the above ranges, so I'll leave the question open.
I would suggest that, rather than using a range of versions, use a specific version you know works. That way, there won't be any problems.
I think that one of the versions of the dependencies is incompatible with the main module, and since it is within the range of versions you ask for, pip tries to intall it and fails to do so since it is incompatible.
Also, pip normally handles dependencies automatically.

Pip wheel collects 2 versions of a package then pip install gets a conflict

We use a pipeline that first uses pip wheel to collect all the packages that are needed in the project and then it creates a docker image that calls to pip install on the collected wheels.
The issue I am encountering is that when calling pip wheel, pip is collecting 2 different versions of a package. This has started occurring once a new version of the package is available.
The project has a requirement for an internal library ecs-deployer==10.1.2 and that library has in turn a requirement in the form of: elb-listener>=3.2.1+25,<4
The relevant output of pip wheel with the verbose option says:
Collecting elb-listener>=3.2.1+25,<4
Created temporary directory: /tmp/pip-unpack-zr930807
File was already downloaded /home/user/path/dist/elb_listener-3.2.2+26-py3-none-any.whl
Added elb-listener>=3.2.1+25,<4 from https://internal-repository.com/path/elb_listener/3.2.2%2B26/elb_listener-3.2.2%2B26-py3-none-any.whl#md5=foo (from ecs-deployer==10.1.2->service==1.0.0) to build tracker '/tmp/pip-req-tracker-1tz9t5ls'
Removed elb-listener>=3.2.1+25,<4 from https://internal-repository.com/path/elb_listener/3.2.2%2B26/elb_listener-3.2.2%2B26-py3-none-any.whl#md5=blabla (from ecs-deployer==10.1.2->service==1.0.0) to build tracker '/tmp/pip-req-tracker-1tz9t5ls'
And also:
Collecting elb-listener>=3.2.1+25,<4
Created temporary directory: /tmp/pip-unpack-yfnxim_u
File was already downloaded /home/user/path/dist/elb_listener-3.2.3+27-py3-none-any.whl
Added elb-listener>=3.2.1+25,<4 from https://internal-repository.com/path/elb_listener/3.2.3%2B27/elb_listener-3.2.3%2B27-py3-none-any.whl#md5=bar (from ecs-deployer==10.1.2->service==1.0.0) to build tracker '/tmp/pip-req-tracker-1tz9t5ls'
Then when the pip install is called I get this:
ERROR: Cannot install elb-listener 3.2.2+26 (from /opt/elb_listener-3.2.2+26-py3-none-any.whl) and cad-aws-elb-listener-target-group-builder 3.2.3+27 (from /opt/elb_listener-3.2.3+27-py3-none-any.whl) because these package versions have conflicting dependencies.
The conflict is caused by:
The user requested elb-listener 3.2.2+26 (from /opt/elb_listener-3.2.2+26-py3-none-any.whl)
The user requested elb-listener 3.2.3+27 (from /opt/elb_listener-3.2.3+27-py3-none-any.whl)
We use pip 20.2.3 with the option --use-feature=2020-resolver
Is it normal that pip wheel collects several versions of the same package?
If so, can I indicate in any way to either pip wheel to only collect one of the versions or to pip install to only use the latest version?
If not, is there any way to solve this problem? I guess changing the requirement to elb-listener>=3.2.1+27,<4 would solve it, but we don't have direct access to that library and it would take a while for other team to change it.
As per #sinoroc comment, upgrading the python to 3.10 and pip version to 21.2.4 solved this particular issue.
As far as I understood, "local version identifiers" such as 3.2.1+25 are far from usual, apparently they are not meant to be used anywhere public (like PyPI), and that might be the reason for all the trouble here. I am really not sure how well they are supported by Python packaging tools and maybe they confuse the dependency resolution.
Local version identifiers SHOULD NOT be used when publishing upstream projects to a public index server, but MAY be used to identify private builds created directly from the project source. Local version identifiers SHOULD be used by downstream projects when releasing a version that is API compatible with the version of the upstream project identified by the public version identifier, but contains additional changes (such as bug fixes). As the Python Package Index is intended solely for indexing and hosting upstream projects, it MUST NOT allow the use of local version identifiers.
-- "Local version identifiers" section of _PEP 440

How does pip wheel resolves transitive dependencies?

When I run pip wheel sentry-sdk it downloads the following wheel files:
certifi-2020.6.20-py2.py3-none-any.whl
sentry_sdk-0.18.0-py2.py3-none-any.whl
urllib3-1.25.10-py2.py3-none-any.whl
Where sentry_sdk-0.18.0-py2.py3-none-any.whl is the lib I actually want to use and the other ones are transitive dependencies required by this lib to work. I understand that the file is coming from PyPI however what I do not understand is how pip wheel is choosing the version of the aforementioned transitive dependencies.
More Context
My underlying problem is that the resolved version of the urllib3 clashes with another one already added to the pex file of the project I'm working on (I'm using Bazel to generate the pex) I'm considering downgrading the version of urllib3 to match my project's existing one. Looking at the setup.py from the sentry-sdk in GitHub it says it only requires it to be greater than 1.10.0 ("urllib3>=1.10.0") so I think the downgrade would work but I wanted to be sure to avoid production crashes.
Thanks
the current version of pip (2020-10-13) does not have a dependency resolver, it picks the first constraint greedily (so if urllib3 is encountered unbounded first, it will pick the latest version -- even if a later package has a more restrictive requirement)
this is being changed in pip, you can enable the resolver as an opt-in in pip>=20.2 and it will become the default in the future (later this year)

Error when installing django on windows using `pip install django`

I get an error when installing django using pip command
ERROR: After October 2020 you may experience errors when installing or updating
packages. This is because pip will change the way that it resolves dependency conflicts.
We recommend you use --use-feature=2020-resolver to test your packages with the
new resolver before it becomes the default.
drf-yasg 1.17.0 requires six>=1.10.0, but you'll have six 1.9.0 which is incompatible.
can anyone help?
Thanks in advance
According to this announcement, pip will introduce a new dependency resolver in October 2020, which will be more robust but might break some existing setups. Therefore they are suggesting users to try running their pip install scripts at least once (in dev mode) with this option: --use-feature=2020-resolver to anticipate any potential issue before the new resolver becomes the default in October 2020 with pip version 20.3.
On behalf of the PyPA, I am pleased to announce that we have just
released pip 20.2, a new version of pip. You can install it by running
python -m pip install --upgrade pip.
The highlights for this release are:
The beta of the next-generation dependency resolver is available
Faster installations from wheel files Improved handling of wheels
containing non-ASCII file contents Faster pip list using parallelized
network operations Installed packages now contain metadata about
whether they were directly requested by the user (PEP 376’s REQUESTED
file) The new dependency resolver is off by default because it is not
yet ready for everyday use. The new dependency resolver is
significantly stricter and more consistent when it receives
incompatible instructions, and reduces support for certain kinds of
constraints files, so some workarounds and workflows may break. Please
test it with the --use-feature=2020-resolver flag. Please see our
guide on how to test and migrate, and how to report issues. We are
preparing to change the default dependency resolution behaviour and
make the new resolver the default in pip 20.3 (in October 2020).

Stable version of gevent?

There appears to be a stable and unstable version here: https://pypi.python.org/pypi/gevent#downloads
It's not entirely clear to me what the distinctions are. I'm guessing there's a stable version on pip, described under the heading "Get gevent", and there's a separate unstable version on github under the heading "Development".
I simply want to install the stable version for production usage. pip install gevent doesn't seem to be the proper way to do this, since it installs something that has a syntax error in line 289 of hub.py, and looking in there I realized that it's a completely different version of gevent from the most up-to-date version on Github.
How do I install gevent?
It looks like the current version on pypi is a release candidate and partially supports Python 3. If you want a stable version (that doesn't support python 3.x) you could try specifying the specific version when you invoke pip
pip install gevent==1.0.2
Alternately, you can install the version based on a specific commit on Github
pip install git+git://github.com/gevent/gevent.git#egg=gevent
This is what they are referring to as the development version. This means that you will be running the code as it exists on Github which could potentially be buggy but will include all latest changes to the codebase.
As a sidenote, if you're having issues with the version currently on pypi, you can see if the issues are reproducible using the most recent Github changes and submit a bug report to the developers.

Categories