Skip to content

BUG: conda_build.config.get_or_merge_config does not respect exclusive_config_file in presence of CONDA_* env vars #5922

@h-vetinari

Description

@h-vetinari

Checklist

  • I added a descriptive title
  • I searched open reports and couldn't find a duplicate

What happened?

I spent my day rediscovering an old issue in conda-smithy that was worked around with conda-forge/conda-smithy@019cc83. Smithy does

        config = conda_build.config.get_or_merge_config(
            None,
            exclusive_config_file=forge_config["exclusive_config_file"],
            platform=platform,
            arch=arch,
        )

which ends up calling

def _get_or_merge_config(
config: Config | None,
variant: dict[str, Any] | None = None,
**kwargs,
) -> Config:
# This function should only ever be called via get_or_merge_config.
# It only exists for us to monkeypatch a default config when running tests.
if not config:
config = Config(variant=variant)
else:
# decouple this config from whatever was fed in. People must change config by
# accessing and changing this attribute.
config = config.copy()
if kwargs:
config.set_keys(**kwargs)
if variant:
config.variant.update(variant)
return config
def get_or_merge_config(
config: Config | None,
variant: dict[str, Any] | None = None,
**kwargs,
) -> Config:
"""Always returns a new object - never changes the config that might be passed in."""
return _get_or_merge_config(config, variant=variant, **kwargs)

We see that exclusive_config_file isn't handled, except that we fall into the config.set_keys(**kwargs) branch. In that function,

def set_keys(self, **kwargs):
def env(lang, default):
version = kwargs.pop(lang, None)
if not version:
# Hooray for corner cases.
if lang == "python":
lang = "py"
elif lang == "numpy":
lang = "npy"
elif lang == "r_base":
lang = "r"
var = "CONDA_" + lang.upper()
version = os.getenv(var) if os.getenv(var) else default
elif isinstance(version, list) and len(version) == 1:
version = version[0]
return version
def set_lang(variant, lang):
value = env(lang, self.variant.get(lang))
if value:
if "." not in str(value):
value = ".".join((value[0], value[1:]))
variant[lang] = value
# this is where we override any variant config files with the legacy CONDA_* vars
# or CLI params
for lang in ("perl", "lua", "python", "numpy", "r_base"):
set_lang(self.variant, lang)

the code ends up unconditionally setting

 'variant': {'lua': '5.',
             'numpy': '1.26',
             'perl': '5.26',
             'python': '3.13',
             'r_base': '3.5'},

on the config object based on the values of CONDA_PY, CONDA_NP, etc. This then causes issues with conflicting variants, mis-matched zips etc. with our global pinning.

The bug here is that conda-build should not set default values in the variant, at the very least not when exclusive_config_file is set.

Conda Info

Details
++ conda info

     active environment : base
    active env location : /opt/conda
            shell level : 1
       user config file : /home/conda/.condarc
 populated config files : /opt/conda/.condarc
                          /opt/conda/condarc.d/anaconda-auth.yml
                          /home/conda/.condarc
          conda version : 26.1.0
    conda-build version : 26.1.0
         python version : 3.12.12.final.0
                 solver : libmamba (default)
       virtual packages : __archspec=1=zen2
                          __conda=26.1.0=0
                          __glibc=2.34=0
                          __linux=6.14.0=0
                          __unix=0=0
       base environment : /opt/conda  (writable)
      conda av data dir : /opt/conda/etc/conda
  conda av metadata url : None
           channel URLs : https://conda.anaconda.org/conda-forge/linux-64
                          https://conda.anaconda.org/conda-forge/noarch
          package cache : /home/conda/feedstock_root/build_artifacts/pkg_cache
                          /opt/conda/pkgs
       envs directories : /opt/conda/envs
                          /home/conda/.conda/envs
    temporary directory : /tmp
               platform : linux-64
             user-agent : conda/26.1.0 requests/2.32.5 CPython/3.12.12 Linux/6.14.0-1017-azure almalinux/9.7 glibc/2.34 solver/libmamba conda-libmamba-solver/25.11.0 libmambapy/2.5.0
                UID:GID : 1001:1001
             netrc file : None
           offline mode : False

Conda Config

Details
++ conda config --env --show-sources
==> /opt/conda/.condarc <==
add_pip_as_python_dependency: False
auto_update_conda: False
aggressive_update_packages:
  - ca-certificates
  - certifi
channel_priority: strict
channels:
  - conda-forge
show_channel_urls: True
conda_build:
  pkg_format: 2
  zstd_compression_level: 19

==> /opt/conda/condarc.d/anaconda-auth.yml <==
channel_settings:
  - frozendict.frozendict({'channel': 'https://repo.anaconda.cloud/*', 'auth': 'anaconda-auth'})

==> /home/conda/.condarc <==
pkgs_dirs:
  - /home/conda/feedstock_root/build_artifacts/pkg_cache
  - /opt/conda/pkgs
solver: libmamba
conda-build:
  root-dir: /home/conda/feedstock_root/build_artifacts

==> envvars <==
allow_softlinks: False
bld_path: /home/conda/feedstock_root/build_artifacts

Conda list

Details
++ conda list --show-channel-urls
# packages in environment at /opt/conda:
#
# Name                        Version          Build                 Channel
_libgcc_mutex                 0.1              conda_forge           conda-forge
_openmp_mutex                 4.5              2_gnu                 conda-forge
anaconda-auth                 0.12.3           pyhd8ed1ab_0          conda-forge
anaconda-cli-base             0.8.1            pyhcf101f3_0          conda-forge
anaconda-client               1.14.1           pyhcf101f3_0          conda-forge
annotated-doc                 0.0.4            pyhcf101f3_0          conda-forge
annotated-types               0.7.0            pyhd8ed1ab_1          conda-forge
archspec                      0.2.5            pyhd8ed1ab_0          conda-forge
attrs                         25.4.0           pyhcf101f3_1          conda-forge
backports                     1.0              pyhd8ed1ab_5          conda-forge
backports.tarfile             1.2.0            pyhcf101f3_2          conda-forge
backports.zstd                1.3.0            py312h90b7ffd_0       conda-forge
beautifulsoup4                4.14.3           pyha770c72_0          conda-forge
boltons                       25.0.0           pyhd8ed1ab_0          conda-forge
brotli-python                 1.2.0            py312hdb49522_1       conda-forge
bzip2                         1.0.8            hda65f42_8            conda-forge
c-ares                        1.34.6           hb03c661_0            conda-forge
ca-certificates               2026.1.4         hbd8a1cb_0            conda-forge
certifi                       2026.1.4         pyhd8ed1ab_0          conda-forge
cffi                          2.0.0            py312h460c074_1       conda-forge
chardet                       5.2.0            pyhd8ed1ab_3          conda-forge
charset-normalizer            3.4.4            pyhd8ed1ab_0          conda-forge
click                         8.3.1            pyh8f84b5b_1          conda-forge
colorama                      0.4.6            pyhd8ed1ab_1          conda-forge
conda                         26.1.0           py312h7900ff3_0       conda-forge
conda-build                   26.1.0           pyh31ec981_2          conda-forge
conda-env                     2.6.0            1                     conda-forge
conda-forge-ci-setup          4.24.2           py312hef7310e_101     conda-forge
conda-forge-metadata          0.12.0           pyhcf101f3_1          conda-forge
conda-index                   0.7.0            pyhd8ed1ab_0          conda-forge
conda-libmamba-solver         25.11.0          pyhd8ed1ab_1          conda-forge
conda-oci-mirror              0.2.3            pyhd8ed1ab_0          conda-forge
conda-package-handling        2.4.0            pyh7900ff3_2          conda-forge
conda-package-streaming       0.12.0           pyhd8ed1ab_0          conda-forge
cpp-expected                  1.3.1            h171cf75_0            conda-forge
cryptography                  46.0.5           py312ha4b625e_0       conda-forge
dbus                          1.16.2           h24cb091_1            conda-forge
defusedxml                    0.7.1            pyhd8ed1ab_0          conda-forge
deprecated                    1.3.1            pyhd8ed1ab_1          conda-forge
distro                        1.9.0            pyhd8ed1ab_1          conda-forge
evalidate                     2.0.5            pyhe01879c_0          conda-forge
filelock                      3.20.3           pyhd8ed1ab_0          conda-forge
fmt                           12.1.0           hff5e90c_0            conda-forge
frozendict                    2.4.7            py312h4c3975b_0       conda-forge
git                           2.52.0           pl5321h6d3cee1_1      conda-forge
h2                            4.3.0            pyhcf101f3_0          conda-forge
hpack                         4.1.0            pyhd8ed1ab_0          conda-forge
hyperframe                    6.1.0            pyhd8ed1ab_0          conda-forge
icu                           78.2             h33c6efd_0            conda-forge
idna                          3.11             pyhd8ed1ab_0          conda-forge
importlib-metadata            8.7.0            pyhe01879c_1          conda-forge
importlib_resources           6.5.2            pyhd8ed1ab_0          conda-forge
jaraco.classes                3.4.0            pyhcf101f3_3          conda-forge
jaraco.context                6.1.0            pyhcf101f3_0          conda-forge
jaraco.functools              4.4.0            pyhcf101f3_1          conda-forge
jeepney                       0.9.0            pyhd8ed1ab_0          conda-forge
jinja2                        3.1.6            pyhcf101f3_1          conda-forge
joblib                        1.5.3            pyhd8ed1ab_0          conda-forge
jq                            1.8.1            h73b1eb8_0            conda-forge
jsonpatch                     1.33             pyhd8ed1ab_1          conda-forge
jsonpointer                   3.0.0            pyhcf101f3_3          conda-forge
jsonschema                    4.26.0           pyhcf101f3_0          conda-forge
jsonschema-specifications     2025.9.1         pyhcf101f3_0          conda-forge
jupyter_core                  5.9.1            pyhc90fa1f_0          conda-forge
keyring                       25.7.0           pyha804496_0          conda-forge
keyutils                      1.6.3            hb9d3cd8_0            conda-forge
krb5                          1.21.3           h659f571_0            conda-forge
lcms2                         2.18             h0c24ade_0            conda-forge
ld_impl_linux-64              2.45.1           default_hbd61a6d_101  conda-forge
lerc                          4.0.0            h0aef613_1            conda-forge
libarchive                    3.8.5            gpl_hc2c16d8_100      conda-forge
libcurl                       8.18.0           h4e3cde8_0            conda-forge
libdeflate                    1.25             h17f619e_0            conda-forge
libedit                       3.1.20250104     pl5321h7949ede_0      conda-forge
libev                         4.33             hd590300_2            conda-forge
libexpat                      2.7.3            hecca717_0            conda-forge
libffi                        3.5.2            h3435931_0            conda-forge
libfreetype                   2.14.1           ha770c72_0            conda-forge
libfreetype6                  2.14.1           h73754d4_0            conda-forge
libgcc                        15.2.0           he0feb66_17           conda-forge
libgcc-ng                     15.2.0           h69a702a_17           conda-forge
libglib                       2.86.3           h6548e54_0            conda-forge
libgomp                       15.2.0           he0feb66_17           conda-forge
libiconv                      1.18             h3b78370_2            conda-forge
libjpeg-turbo                 3.1.2            hb03c661_0            conda-forge
liblief                       0.17.1           hecca717_0            conda-forge
liblzma                       5.8.2            hb03c661_0            conda-forge
liblzma-devel                 5.8.2            hb03c661_0            conda-forge
libmamba                      2.5.0            hd28c85e_0            conda-forge
libmamba-spdlog               2.5.0            h12fcf84_0            conda-forge
libmambapy                    2.5.0            py312h1ca65c7_0       conda-forge
libnghttp2                    1.67.0           had1ee68_0            conda-forge
libnsl                        2.0.1            hb9d3cd8_1            conda-forge
libpng                        1.6.55           h421ea60_0            conda-forge
libsolv                       0.7.35           h9463b59_0            conda-forge
libsqlite                     3.51.2           hf4e2dac_0            conda-forge
libssh2                       1.11.1           hcf80075_0            conda-forge
libstdcxx                     15.2.0           h934c35e_17           conda-forge
libstdcxx-ng                  15.2.0           hdf11a46_17           conda-forge
libtiff                       4.7.1            h9d88235_1            conda-forge
libuuid                       2.41.3           h5347b49_0            conda-forge
libwebp-base                  1.6.0            hd42ef1d_0            conda-forge
libxcb                        1.17.0           h8a09558_0            conda-forge
libxcrypt                     4.4.36           hd590300_1            conda-forge
libxml2                       2.15.1           he237659_1            conda-forge
libxml2-16                    2.15.1           hca6bf5a_1            conda-forge
libzlib                       1.3.1            hb9d3cd8_2            conda-forge
lz4-c                         1.10.0           h5888daf_1            conda-forge
lzo                           2.10             h280c20c_1002         conda-forge
mamba                         2.5.0            h9835478_0            conda-forge
markdown-it-py                4.0.0            pyhd8ed1ab_0          conda-forge
markupsafe                    3.0.3            py312h8a5da7c_0       conda-forge
mbedtls                       3.6.3.1          h5888daf_0            conda-forge
mdurl                         0.1.2            pyhd8ed1ab_1          conda-forge
menuinst                      2.4.2            py312h7900ff3_0       conda-forge
more-itertools                10.8.0           pyhcf101f3_1          conda-forge
msgpack-python                1.1.2            py312hd9148b4_1       conda-forge
nbformat                      5.10.4           pyhd8ed1ab_1          conda-forge
ncurses                       6.5              h2d0b736_3            conda-forge
nlohmann_json-abi             3.12.0           h0f90c79_1            conda-forge
oniguruma                     6.9.10           hb9d3cd8_0            conda-forge
openjpeg                      2.5.4            h55fea9a_0            conda-forge
openssl                       3.6.1            h35e630c_1            conda-forge
oras-py                       0.1.14           pyhd8ed1ab_0          conda-forge
packaging                     26.0             pyhcf101f3_0          conda-forge
patch                         2.8              hb03c661_1002         conda-forge
patchelf                      0.17.2           h58526e2_0            conda-forge
pcre2                         10.47            haa7fec5_0            conda-forge
perl                          5.32.1           7_hd590300_perl5      conda-forge
pillow                        12.1.1           py312h50c33e8_0       conda-forge
pip                           26.0.1           pyh8b19718_0          conda-forge
pixi                          0.63.2           ha759004_0            conda-forge
pkce                          1.0.3            pyhd8ed1ab_1          conda-forge
pkginfo                       1.12.1.2         pyhd8ed1ab_0          conda-forge
platformdirs                  4.5.1            pyhcf101f3_0          conda-forge
pluggy                        1.6.0            pyhf9edf01_1          conda-forge
psutil                        7.2.2            py312h5253ce2_0       conda-forge
pthread-stubs                 0.4              hb9d3cd8_1002         conda-forge
py-lief                       0.17.1           py312h1289d80_0       conda-forge
pybind11-abi                  11               hc364b38_1            conda-forge
pycosat                       0.6.6            py312h4c3975b_3       conda-forge
pycparser                     2.22             pyh29332c3_1          conda-forge
pydantic                      2.12.5           pyhcf101f3_1          conda-forge
pydantic-core                 2.41.5           py312h868fb18_1       conda-forge
pydantic-settings             2.12.0           pyh3cfb1c2_0          conda-forge
pygments                      2.19.2           pyhd8ed1ab_0          conda-forge
pyjwt                         2.11.0           pyhd8ed1ab_0          conda-forge
pysocks                       1.7.1            pyha55dd90_7          conda-forge
python                        3.12.12          hd63d673_2_cpython    conda-forge
python-dateutil               2.9.0.post0      pyhe01879c_2          conda-forge
python-dotenv                 1.2.1            pyhcf101f3_0          conda-forge
python-fastjsonschema         2.21.2           pyhe01879c_0          conda-forge
python-libarchive-c           5.3              pyhe01879c_1          conda-forge
python_abi                    3.12             8_cp312               conda-forge
pytz                          2025.2           pyhd8ed1ab_0          conda-forge
pyyaml                        6.0.3            py312h8a5da7c_1       conda-forge
rattler-build                 0.57.2           he64ecbb_1            conda-forge
rattler-build-conda-compat    1.4.11           pyhd8ed1ab_0          conda-forge
readchar                      4.2.1            pyhe01879c_0          conda-forge
readline                      8.3              h853b02a_0            conda-forge
referencing                   0.37.0           pyhcf101f3_0          conda-forge
reproc                        14.2.5.post0     hb9d3cd8_0            conda-forge
reproc-cpp                    14.2.5.post0     h5888daf_0            conda-forge
requests                      2.32.5           pyhcf101f3_1          conda-forge
requests-toolbelt             1.0.0            pyhd8ed1ab_1          conda-forge
rich                          14.3.2           pyhcf101f3_0          conda-forge
ripgrep                       15.1.0           hdab8a38_0            conda-forge
rpds-py                       0.30.0           py312h868fb18_0       conda-forge
ruamel.yaml                   0.18.17          py312h5253ce2_2       conda-forge
ruamel.yaml.clib              0.2.15           py312h5253ce2_1       conda-forge
secretstorage                 3.4.1            py312h7900ff3_0       conda-forge
semver                        3.0.4            pyhcf101f3_1          conda-forge
setuptools                    82.0.0           pyh332efcf_0          conda-forge
shellingham                   1.5.4            pyhd8ed1ab_2          conda-forge
shyaml                        0.6.2            pyhd3deb0d_0          conda-forge
simdjson                      4.2.4            hb700be7_0            conda-forge
six                           1.17.0           pyhe01879c_1          conda-forge
soupsieve                     2.8.3            pyhd8ed1ab_0          conda-forge
spdlog                        1.17.0           hab81395_1            conda-forge
su-exec                       0.2              h166bdaf_1003         conda-forge
tini                          0.19.0           h166bdaf_1            conda-forge
tk                            8.6.13           noxft_h366c992_103    conda-forge
tomli                         2.4.0            pyhcf101f3_0          conda-forge
tomlkit                       0.14.0           pyha770c72_0          conda-forge
tqdm                          4.67.3           pyh8f84b5b_0          conda-forge
traitlets                     5.14.3           pyhd8ed1ab_1          conda-forge
truststore                    0.10.4           pyhcf101f3_0          conda-forge
typer                         0.21.2           pyhf0a747c_0          conda-forge
typer-slim                    0.21.2           pyhcf101f3_0          conda-forge
typer-slim-standard           0.21.2           h0939d6c_0            conda-forge
typing-extensions             4.15.0           h396c80c_0            conda-forge
typing-inspection             0.4.2            pyhd8ed1ab_1          conda-forge
typing_extensions             4.15.0           pyhcf101f3_0          conda-forge
tzdata                        2025c            hc9c84f9_1            conda-forge
urllib3                       2.6.3            pyhd8ed1ab_0          conda-forge
wheel                         0.46.3           pyhd8ed1ab_0          conda-forge
wrapt                         2.1.1            py312h4c3975b_0       conda-forge
xorg-libxau                   1.0.12           hb03c661_1            conda-forge
xorg-libxdmcp                 1.1.5            hb03c661_1            conda-forge
xz                            5.8.2            ha02ee65_0            conda-forge
xz-gpl-tools                  5.8.2            ha02ee65_0            conda-forge
xz-tools                      5.8.2            hb03c661_0            conda-forge
yaml                          0.2.5            h280c20c_3            conda-forge
yaml-cpp                      0.8.0            h59595ed_0            conda-forge
zipp                          3.23.0           pyhcf101f3_1          conda-forge
zlib-ng                       2.3.3            hceb46e0_1            conda-forge
zstandard                     0.25.0           py312h5253ce2_1       conda-forge
zstd                          1.5.7            hb78ec9c_6            conda-forge

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    type::bugdescribes erroneous operation, use severity::* to classify the type

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions