navneethc
navneethc

Reputation: 1466

Why does conda want to update unrelated packages when I want to remove just one?

Windows 10

conda 4.9.2 (via miniconda)

I installed a single package that did not require any other dependencies to be installed anew or upgraded. Once I realised that I had installed an unsuitable version of the package, I went to remove it, and this is the screen I was presented with:

(pydata) PS C:\Users\Navneeth> conda remove xlrd
Collecting package metadata (repodata.json): done
Solving environment: |
Warning: 2 possible package resolutions (only showing differing packages):
  - defaults/win-64::libtiff-4.1.0-h56a325e_1, defaults/win-64::zstd-1.4.9-h19a0ad4_0
  - defaults/win-64::libtiff-4.2.0-hd0e1b90_0, defaults/win-64::zstd-1.4.5-h04227a9done

## Package Plan ##

  environment location: C:\Users\Navneeth\Miniconda3\envs\pydata

  removed specs:
    - xlrd


The following packages will be downloaded:

    package                    |            build
    ---------------------------|-----------------
    decorator-5.0.3            |     pyhd3eb1b0_0          12 KB
    importlib-metadata-3.7.3   |   py38haa95532_1          31 KB
    importlib_metadata-3.7.3   |       hd3eb1b0_1          11 KB
    ipython-7.22.0             |   py38hd4e2768_0         998 KB
    jupyter_client-6.1.12      |     pyhd3eb1b0_0          88 KB
    libtiff-4.1.0              |       h56a325e_1         739 KB
    nbformat-5.1.3             |     pyhd3eb1b0_0          44 KB
    notebook-6.3.0             |   py38haa95532_0         4.4 MB
    pandoc-2.12                |       haa95532_0        13.2 MB
    parso-0.8.2                |     pyhd3eb1b0_0          69 KB
    pillow-8.2.0               |   py38h4fa10fc_0         671 KB
    prometheus_client-0.10.0   |     pyhd3eb1b0_0          46 KB
    prompt-toolkit-3.0.17      |     pyh06a4308_0         256 KB
    terminado-0.9.4            |   py38haa95532_0          26 KB
    zipp-3.4.1                 |     pyhd3eb1b0_0          15 KB
    zstd-1.4.9                 |       h19a0ad4_0         478 KB
    ------------------------------------------------------------
                                           Total:        21.0 MB

The following packages will be REMOVED:

  xlrd-2.0.1-pyhd3eb1b0_0

The following packages will be UPDATED:

  decorator                              4.4.2-pyhd3eb1b0_0 --> 5.0.3-pyhd3eb1b0_0
  importlib-metadata pkgs/main/noarch::importlib-metadata-~ --> pkgs/main/win-64::importlib-metadata-3.7.3-py38haa95532_1
  importlib_metadata                                2.0.0-1 --> 3.7.3-hd3eb1b0_1
  ipython                             7.21.0-py38hd4e2768_0 --> 7.22.0-py38hd4e2768_0
  jupyter_client                                 6.1.7-py_0 --> 6.1.12-pyhd3eb1b0_0
  nbformat                               5.1.2-pyhd3eb1b0_1 --> 5.1.3-pyhd3eb1b0_0
  notebook                             6.2.0-py38haa95532_0 --> 6.3.0-py38haa95532_0
  pandoc                                    2.11-h9490d1a_0 --> 2.12-haa95532_0
  parso                                  0.8.1-pyhd3eb1b0_0 --> 0.8.2-pyhd3eb1b0_0
  pillow                               8.1.2-py38h4fa10fc_0 --> 8.2.0-py38h4fa10fc_0
  prometheus_client                      0.9.0-pyhd3eb1b0_0 --> 0.10.0-pyhd3eb1b0_0
  prompt-toolkit                                 3.0.8-py_0 --> 3.0.17-pyh06a4308_0
  sqlite                                  3.33.0-h2a8f88b_0 --> 3.35.3-h2bbff1b_0
  terminado                            0.9.2-py38haa95532_0 --> 0.9.4-py38haa95532_0
  zipp                                   3.4.0-pyhd3eb1b0_0 --> 3.4.1-pyhd3eb1b0_0
  zstd                                     1.4.5-h04227a9_0 --> 1.4.9-h19a0ad4_0

The following packages will be DOWNGRADED:

  libtiff                                  4.2.0-he0120a3_0 --> 4.1.0-h56a325e_1


Proceed ([y]/n)?

Why does conda want to update or downgrade all these other packages when the opposite wasn't done when I installed xlrd? Is there a way that I can safely remove the just xlrd. (I hear using --force is risky.)

Upvotes: 7

Views: 1236

Answers (2)

user343233
user343233

Reputation: 125

I have came across the same problem and found one possible way to remove package(s) safely without changing other packages.

Solution

The solution is to "rollback" to the previous version of your environment using conda list --revisions and conda install --revision=REVNUM (or conda install --rev REVNUM).

Example

For example, I have install the package xlrd and want to remove it alone. Simply using conda remove xlrd would affect other packages, just as the OP says. Instead, I choose to restore the environment to the previous version (where I didn't install xlrd package).

First, determine which version needs to be restored. Type conda list --revisions would give:

...

2022-09-05 17:43:08  (rev 8)
    +et_xmlfile-1.1.0 (defaults/linux-64)
    +openpyxl-3.0.9 (defaults/noarch)

2023-11-01 13:16:30  (rev 9)
     ca-certificates  {2022.07.19 (defaults/linux-64) -> 2023.08.22 (defaults/linux-64)}
     openssl  {1.1.1q (defaults/linux-64) -> 1.1.1w (defaults/linux-64)}
    +xlrd-2.0.1 (defaults/noarch)

I want to restore to the version where xlrd is not installed, i.e., rev 8 in this example. So I type conda install --revision=8. Changes to the environment after rev 8 will be undone. Therefore, package xlrd will be removed and package ca-certificates and openssl will be downgraded, just as I haven't type conda install xlrd before.

Remark

The limitation of this approach is that its behavior depends on your installation method. If you only installed one package before, this approach will only remove the package itself, just as what we want. However, if you installed multiple packages at the same time, these packages would be removed together. And you need to reinstall the other packages, which may be a little cumbersome.

Upvotes: 0

merv
merv

Reputation: 76750

Asymmetry

Conda re-solves when removing. When installing, Conda first attempts a frozen solve, which amounts to keeping all installed packages fixed and just searching for a version of the requested package(s) that are compatible. In this specific case, xlrd (v2.1.0) is a noarch with only a python>=3.6 constraint. So this installs in this frozen solve pass.

The constraint xlrd will also be added to the explicit specifications.1

When removing, Conda will first remove the constraint, and then re-solves the environment with the new set of explicit specifications. It is in this solve that Conda identifies that newer versions of packages and then proposes updating then.

So, the asymmetry is that the frozen solve explicitly avoids checking for any new packages, but the removal will trigger such a check. There is not currently a way to avoid this without bypassing dependency checking.


Mamba

Actually, mamba, a compiled (fast!) drop-in replacement for conda, will remove only the specified package if it doesn't have anything depending on it. That is its default behavior in my testing.


Addendum: Still Some Unexplained Behavior

I replicated your experience by first creating an environment with two specs:

name: foo
channels:
  - conda-forge
dependencies:
  - python=3.8.0
  - pip=20

To simulate this being an old environment, I went into the envs/foo/conda-meta/history and changed2 the line

# update specs: ['pip=20', 'python=3.8.0']

to

# update specs: ['python=3.8']

Subsequently running conda install xlrd does as expected. Then conda remove xlrd gives a somewhat odd result:

## Package Plan ##

  environment location: /opt/conda/envs/foo

  removed specs:
    - xlrd


The following packages will be downloaded:

    package                    |            build
    ---------------------------|-----------------
    pip-21.1.1                 |     pyhd8ed1ab_0         1.1 MB  conda-forge
    ------------------------------------------------------------
                                           Total:         1.1 MB

The following packages will be REMOVED:

  xlrd-2.0.1-pyhd8ed1ab_3

The following packages will be UPDATED:

  pip                                   20.3.4-pyhd8ed1ab_0 --> 21.1.1-pyhd8ed1ab_0


Proceed ([y]/n)?

This effectively replicates OP result, however, the additional oddity here is that the python package is not suggested to be updated, even though I had intentionally loosened its constraint from 3.8.0 to 3.8. It appears that only packages not in the explicit specifications are subject to updating during package removal.


[1] The explicit specifications are the internally maintained records that Conda keeps of every constraint a user has explicitly specified. One can view the current explicit specifications of an environment with conda env export --from-history. The raw internal records can be found at yourenv/conda-meta/history.

[2] Not a recommended practice!

Upvotes: 5

Related Questions