Developer Guide: A Tale of Five Prefixes

In the realm of package management and environment configuration, conda has
emerged as a versatile tool empowering developers with environment management. A
pivotal aspect of conda's architecture lies in its prefix system, which
underwent a significant evolution over its previous versions, transforming conda from a
simple package manager into a sprawling environment manager. In this technical
discourse, we delve into the intricacies of conda's prefix system, shedding
light on its evolution and the five distinct prefixes delineated within the
conda source code.
In the nascent stages of conda's development, its primary functionality
revolved around installing packages into a singular environment, at the time
referred to as the root environment. This era, marked by conda versions
preceding 4.2.0, laid the groundwork for conda's subsequent evolution as an
environment manager.
With the advent of conda 4.2.0 and beyond, a paradigm shift
occurred when the conda-env project was merged with the
conda project, elevating conda from a mere package manager to a
comprehensive environment manager. This pivotal transformation bestowed upon
conda the capability to create and manage separate environments, fostering
modularity and flexibility in development workflows.
Delving into conda's Git history via git blame provides invaluable insights
into the timeline of the prefix system evolution. By tracing the commit history,
we unearthed pivotal moments that introduced and refined the various prefixes
integral to conda's architecture. The history reveals two distinct phases in
the evolution of conda's prefix system. The first phase occurred early on in
conda 1.x and the second phase much later in conda 4.x with the merging of
conda-env with conda.
Here are the five prefixes defined within conda, ordered from the lowest level (system-level and least configurable) to the highest level (user-level and most configurable):
conda.base.context.context.conda_prefix
Introduced in conda 4.2.0 (see https://github.com/conda/conda/commit/6e730cc)
as part of the private environment effort, which has since been abandoned and
deprecated.
The conda_prefix lies at the heart of the prefix system, denoting the
installation directory of conda itself. Typically, this aligns with the
location of the base environment and is equivalent to Python's sys.prefix
value.
Use this any time you need to interact with the conda installation itself.
conda.base.context.context.root_prefix
● conda.config.ROOT_DIR
↓ conda.config.root_dir
○ conda.base.context.context.root_prefix
Introduced in conda 1.1.0 (see https://github.com/conda/conda/commit/d2b370a)
and was originally intended for testing purposes only.
The root_prefix serves as a configurable value, most easily
configurable in the user's ~/.condarc file. In the absence of user-defined
preferences, it defaults to the conda_prefix.
Avoid using this. This is a contender for deprecation.
conda.base.context.context.active_prefix
Introduced in conda 4.4.0 (see https://github.com/conda/conda/commit/cbbe81f)
as part of cleaning up the conda info output.
Reflecting the currently active environment, the active_prefix is determined
by the $CONDA_PREFIX environment variable, which is set by the conda activate
and conda deactivate commands.
Avoid using this. Treat this as an internal value.
conda.base.context.context.default_prefix
● conda.anaconda.default_environment
↓ conda.config.default_environment
↓ conda.config.DEFAULT_ENV_PREFIX
↓ conda.config.default_prefix
○ conda.base.context.context.default_prefix
Introduced in conda 1.1.0 (see https://github.com/conda/conda/commit/acd8144)
as part of a larger configuration overhaul.
The default_prefix is the same as active_prefix when an environment is
active. When no environment is active the default environment is returned
(which can be overridden via the $CONDA_DEFAULT_ENV environment variable)
and otherwise defaults to the root_prefix.
Avoid using this. Treat this as an internal value.
conda.base.context.context.target_prefix
● conda.cli.utils.get_prefix()
↓ conda.cli.common.get_prefix()
↓ conda.base.context.context.prefix
○ conda.base.context.context.target_prefix
Introduced in conda 1.3.0 (see https://github.com/conda/conda/commit/9fd0f4b)
to abstract out the --name/--prefix logic from the CLI implementations.
The target_prefix is the highest level prefix and reflects the user input
via the CLI options, --name or --prefix. In the absence of CLI overrides,
it defaults to the default_prefix.
Use this when you need to interact with the current environment.
In essence, the conda prefix system serves as the cornerstone of its environment
management capabilities, facilitating seamless navigation and interaction within
the different environments a user may have created. As conda continues to
evolve, understanding its prefix system remains paramount for harnessing its
capabilities effectively and correctly.

