Search code examples
condaenvironment

Remove all packages from conda environment that are not included in environment.yml


Suppose I have manually added some packages to some_environment, which is created using environment.yml, how would I efficiently remove all packages that are not specified in the environment.yml?

One solution is to delete the environment and re-create it from the environment.yml however, I would expect it can be faster by only deleting those that are unused, instead of deleting everything and then re-installing the used ones.


Solution

  • Conda's --prune is broken

    The conda env update --prune command should do this, but I just tested it and it does not work. See bug report.

    py311.yaml

    name: py311
    channels:
      - conda-forge
    dependencies:
      - python =3.11
    

    Commands

    ## create the environment from YAML
    conda env create -n foo -f py311.yaml
    
    ## ad hoc install a package not in YAML
    conda install -n foo numpy
    
    ## attempt using the `--prune` argument to revert
    conda env update --prune -n foo -f py311.yaml
    
    ## check if numpy is still installed (it shouldn't be)
    conda list -n foo numpy
    # packages in environment at /Users/mfansler/mambaforge-arm64/envs/foo:
    #
    # Name                    Version                   Build  Channel
    # numpy                     1.24.1          py311ha92fb03_0    conda-forge
    
    
    # shucks! - it's still there
    

    Mamba's --prune works!

    Fortunately, the Mamba implementation of the --prune operation works as expected. Continuing from the environment above:

    ## install Mamba if you don't have it
    # conda install -n base -c conda-forge mamba
    
    ## prune with mamba
    mamba env update --prune -n foo -f py311.yaml
    
    ## check that numpy is gone
    mamba list -n foo numpy
    # packages in environment at /Users/mfansler/mambaforge-arm64/envs/foo:
    #
    # Name                    Version                   Build  Channel
    
    ## there's no match - great!
    

    Minor Note on Explicit & Implicit Specifications

    It may be worth clarifying that the request:

    "remove all packages that are not specified in the environment.yml"

    could be interpreted as meaning all packages not explicitly specified. That would not be possible, since many packages also have unavoidable dependencies.

    For example, even though python=3.11 is the only explicit specification given above, it is impossible to have a functional Python without also including dependencies (implicit specifications). There is no mechanism to remove everything not explicitly specified, mostly because that would lead to a broken environment. A more precise expression for the solution presented here might be "remove all packages not required by the explicitly specified packages".

    I only mention this because I've seen such an interpretation in the wild - not because I think this is OP's intent. Just trying to cover all the bases.