From 0e5bd036dd461fad895581f9ff822374206067c1 2024-09-12 02:39:45 From: Shaun Walbridge Date: 2024-09-12 02:39:45 Subject: [PATCH] Use environment variable to identify conda / mamba Conda and mamba both set an environment variable which refers to the base environment's executable path, use that in preference to less reliable methods, but fall back on the other approaches if unable to locate the executable this way. Additionally, change the search to look for the bare command name rather than the command within the top level of the active environment, I'm dubious this approach works with any current conda / mamba version which usually place their executable links in a `condabin` directory or elsewhere not at the same level as the Python executable. --- diff --git a/IPython/core/magics/packaging.py b/IPython/core/magics/packaging.py index 093b0a2..b335e7e 100644 --- a/IPython/core/magics/packaging.py +++ b/IPython/core/magics/packaging.py @@ -9,6 +9,7 @@ #----------------------------------------------------------------------------- import functools +import os import re import shlex import sys @@ -41,6 +42,16 @@ def _get_conda_like_executable(command): executable: string Value should be: conda, mamba or micromamba """ + # Check for a environment variable bound to the base executable, both conda and mamba + # set these when activating an environment. + base_executable = "CONDA_EXE" + if 'mamba' in command.lower(): + base_executable = "MAMBA_EXE" + if base_executable in os.environ: + executable = Path(os.environ[base_executable]) + if executable.is_file(): + return str(executable.resolve()) + # Check if there is a conda executable in the same directory as the Python executable. # This is the case within conda's root environment. executable = Path(sys.executable).parent / command @@ -48,10 +59,12 @@ def _get_conda_like_executable(command): return str(executable) # Otherwise, attempt to extract the executable from conda history. - # This applies in any conda environment. + # This applies in any conda environment. Parsing this way is error prone because + # different versions of conda and mamba include differing cmd values such as + # `conda`, `conda-script.py`, or `path/to/conda`, here use the raw command provided. history = Path(sys.prefix, "conda-meta", "history").read_text(encoding="utf-8") match = re.search( - rf"^#\s*cmd:\s*(?P.*{executable})\s[create|install]", + rf"^#\s*cmd:\s*(?P.*{command})\s[create|install]", history, flags=re.MULTILINE, )