67 lines
2.1 KiB
Python
67 lines
2.1 KiB
Python
|
|
"""Utilities for locating conda-environment Python interpreters at launch time."""
|
||
|
|
|
||
|
|
import os
|
||
|
|
|
||
|
|
|
||
|
|
def find_conda_python(env_name: str) -> str:
|
||
|
|
"""Return the path to ``python3`` inside a named conda environment.
|
||
|
|
|
||
|
|
Resolution order
|
||
|
|
----------------
|
||
|
|
1. ``<ENV_NAME_UPPER>_PYTHON`` environment variable (explicit override).
|
||
|
|
e.g. for *mmpose*: ``MMPOSE_PYTHON=/path/to/python3``
|
||
|
|
2. ``CONDA_EXE`` environment variable — set by ``conda init`` and points to
|
||
|
|
the conda binary inside the base installation. The base directory is two
|
||
|
|
levels up (``<base>/bin/conda → <base>``).
|
||
|
|
3. A scan of common conda base-directory locations.
|
||
|
|
|
||
|
|
Parameters
|
||
|
|
----------
|
||
|
|
env_name:
|
||
|
|
Name of the conda environment (e.g. ``"mmpose"``).
|
||
|
|
|
||
|
|
Returns
|
||
|
|
-------
|
||
|
|
str
|
||
|
|
Absolute path to the Python 3 interpreter.
|
||
|
|
|
||
|
|
Raises
|
||
|
|
------
|
||
|
|
FileNotFoundError
|
||
|
|
If no interpreter is found through any of the above methods.
|
||
|
|
"""
|
||
|
|
# 1. Explicit override via environment variable
|
||
|
|
override_var = f"{env_name.upper()}_PYTHON"
|
||
|
|
if p := os.environ.get(override_var):
|
||
|
|
return p
|
||
|
|
|
||
|
|
rel = os.path.join("envs", env_name, "bin", "python3")
|
||
|
|
|
||
|
|
# 2. Derive conda base from CONDA_EXE (most reliable when conda is initialised)
|
||
|
|
if conda_exe := os.environ.get("CONDA_EXE"):
|
||
|
|
base = os.path.dirname(os.path.dirname(conda_exe))
|
||
|
|
candidate = os.path.join(base, rel)
|
||
|
|
if os.path.isfile(candidate):
|
||
|
|
return candidate
|
||
|
|
|
||
|
|
# 3. Scan common install locations
|
||
|
|
common_bases = [
|
||
|
|
"~/miniconda3",
|
||
|
|
"~/anaconda3",
|
||
|
|
"~/mambaforge",
|
||
|
|
"~/miniforge3",
|
||
|
|
"~/opt/miniconda3",
|
||
|
|
"/opt/conda",
|
||
|
|
"/opt/miniconda3",
|
||
|
|
"/opt/anaconda3",
|
||
|
|
]
|
||
|
|
for base in common_bases:
|
||
|
|
candidate = os.path.join(os.path.expanduser(base), rel)
|
||
|
|
if os.path.isfile(candidate):
|
||
|
|
return candidate
|
||
|
|
|
||
|
|
raise FileNotFoundError(
|
||
|
|
f"Cannot locate Python for conda env '{env_name}'. "
|
||
|
|
f"Set the {override_var} environment variable to the full path of the interpreter."
|
||
|
|
)
|