From d23bee0cb5216d2e9ce752b47f67e559a18e8e6b 2024-10-01 08:02:04 From: M Bussonnier Date: 2024-10-01 08:02:04 Subject: [PATCH] Use environment variable to identify conda / mamba (#14515) 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. I believe this will also address https://github.com/ipython/ipython/issues/14350, which I'm also seeing in a Windows context where the regex fails to parse and causes a traceback. --- diff --git a/IPython/core/magics/packaging.py b/IPython/core/magics/packaging.py index 093b0a2..09d4117 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, )