Skip to content

python variant is excluded from the generated package content hash #6070

Description

Checklist

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

What happened?

When building a recipe like this:

package:
  name: test
  version: 0.0.0

requirements:
  build:
    - {{ compiler('c') }}
  host:
    - python
  run:
    - python {{ python }}

build:
  string: py{{ PY_VER | replace(".", "") }}{{ PKG_HASH }}
  script: {{ PYTHON }} {{ python }}

and a conda_build_config.yaml that looks like this:

c_compiler:
  - gcc
c_compiler_version:
  - 15.2.0
python:
  - 3.13
  - 3.14

the resulting content hash contains this:

{'c_compiler': 'gcc',
 'c_compiler_version': '15.2.0',
 'channel_targets': 'defaults',
 'target_platform': 'linux-aarch64'}

Conda Info

active environment : base
    active env location : /Users/jcmorin/miniconda
            shell level : 1
       user config file : /Users/jcmorin/.condarc
 populated config files : /Users/jcmorin/.condarc
          conda version : 26.5.3
    conda-build version : 26.5.0
         python version : 3.14.6.final.0
                 solver : rattler
       virtual packages : __archspec=1=m2
                          __conda=26.5.3=0
                          __osx=26.5.1=0
                          __unix=0=0
       base environment : /Users/jcmorin/miniconda  (writable)
      conda av data dir : /Users/jcmorin/miniconda/etc/conda
  conda av metadata url : None
           channel URLs : https://repo.anaconda.com/pkgs/main/osx-arm64
                          https://repo.anaconda.com/pkgs/main/noarch
                          https://repo.anaconda.com/pkgs/r/osx-arm64
                          https://repo.anaconda.com/pkgs/r/noarch
          package cache : /Users/jcmorin/miniconda/pkgs
                          /Users/jcmorin/.conda/pkgs
       envs directories : /Users/jcmorin/miniconda/envs
                          /Users/jcmorin/.conda/envs
    temporary directory : /var/folders/v9/_ts489v53q53dld4jg5sqz_m0000gp/T
               platform : osx-arm64
             user-agent : conda/26.5.3 requests/2.34.2 CPython/3.14.6 Darwin/25.5.0 OSX/26.5.1 solver/rattler conda-rattler-solver/0.1.1 py-rattler/0.25.0 aau/0.8.1 c/. s/. e/. o/.
                UID:GID : 502:20
             netrc file : None
           offline mode : False

Conda Config

==> /Users/jcmorin/.condarc <==
channels:
  - defaults
report_errors: False
solver: rattler
conda_build:
  pkg_format: 2

==> envvars <==
allow_softlinks: False

Conda list

# packages in environment at /Users/jcmorin/miniconda:
#
# Name                       Version          Build               Channel
anaconda-anon-usage          0.8.1            pyhb46e38b_100      defaults
annotated-types              0.7.0            py314hca03da5_0     defaults
anyio                        4.12.1           py314hca03da5_0     defaults
archspec                     0.2.6            py314hca03da5_0     defaults
attrs                        26.1.0           py314h0d18f5d_0     defaults
backports.zstd               1.3.0            py314h8e8c7c1_0     defaults
beautifulsoup4               4.15.0           py314hca03da5_0     defaults
boltons                      25.0.0           py314hca03da5_0     defaults
brotlicffi                   1.2.0.0          py314h50f4ffc_0     defaults
bzip2                        1.0.8            h80987f9_6          defaults
c-ares                       1.34.7           hfe05a68_0          defaults
ca-certificates              2026.7.16        hca03da5_0          defaults
cctools                      1030.6.3         h0aecbd0_1          defaults
certifi                      2026.7.22        py314hca03da5_0     defaults
cffi                         2.1.0            py314h73c2a22_0     defaults
chardet                      5.2.0            py314hca03da5_0     defaults
charset-normalizer           3.4.7            py314hca03da5_0     defaults
click                        8.4.1            py314hca03da5_0     defaults
conda                        26.5.3           py314hca03da5_0     defaults
conda-build                  26.5.0           py314h4f616cb_0     defaults
conda-content-trust          0.3.2            py314hca03da5_0     defaults
conda-index                  0.12.1           py314hca03da5_0     defaults
conda-libmamba-solver        26.7.0           pyh3785b3c_0        defaults
conda-lockfiles              0.2.1            py314hca03da5_0     defaults
conda-package-handling       2.5.0            py314hca03da5_0     defaults
conda-package-streaming      0.13.0           py314hca03da5_0     defaults
conda-pypi                   0.11.0           py314hca03da5_0     defaults
conda-rattler-solver         0.1.1            py314hca03da5_0     defaults
conda-self                   0.2.1            py314hca03da5_0     defaults
cpp-expected                 1.1.0            h48ca7d4_0          defaults
cryptography                 49.0.0           py314h482b559_0     defaults
distro                       1.9.0            py314hca03da5_0     defaults
evalidate                    2.1.4            py314hca03da5_0     defaults
filelock                     3.29.4           py314hca03da5_0     defaults
fmt                          12.1.0           hc20ec9e_0          defaults
frozendict                   2.4.7            py314haa24f5a_0     defaults
gettext                      0.25.1           h0087489_2          defaults
gettext-tools                0.25.1           h47834f4_2          defaults
glob2                        0.7              pyhd3eb1b0_0        defaults
h11                          0.16.0           py314hca03da5_1     defaults
httpcore                     1.0.9            py314hca03da5_0     defaults
httpx                        0.28.1           py314hca03da5_1     defaults
icu                          78.3             hb5f10ac_1          defaults
idna                         3.18             py314hca03da5_0     defaults
jansson                      2.15.0           h9db958f_0          defaults
jinja2                       3.1.6            py314hca03da5_0     defaults
jsonpatch                    1.33             py314hca03da5_1     defaults
jsonpointer                  3.1.1            py314hca03da5_0     defaults
jsonschema                   4.25.1           py314hca03da5_0     defaults
jsonschema-specifications    2025.9.1         py314hca03da5_0     defaults
ld64                         956.6            haf59c80_1          defaults
libarchive                   3.8.8            h2304516_1          defaults
libasprintf                  0.25.1           hcc4682f_2          defaults
libasprintf-devel            0.25.1           hcc4682f_2          defaults
libbrotlicommon              1.2.0            hbd7815e_0          defaults
libbrotlidec                 1.2.0            h1e834b2_0          defaults
libbrotlienc                 1.2.0            h5439a07_0          defaults
libcurl                      8.21.0           h033922a_0          defaults
libcxx                       22.1.2           hf894667_0          defaults
libev                        4.33             h1a28f6b_1          defaults
libexpat                     2.8.2            h50f4ffc_1          defaults
libffi                       3.4.8            h4a3ca97_3          defaults
libgettextpo                 0.25.1           hd3943a6_2          defaults
libgettextpo-devel           0.25.1           hd3943a6_2          defaults
libiconv                     1.18             h92f5915_0          defaults
libidn2                      2.3.8            h9681e36_0          defaults
libintl                      0.25.1           h55097f8_2          defaults
libintl-devel                0.25.1           h55097f8_2          defaults
libkrb5                      1.22.2           hbbdc3aa_0          defaults
liblief                      0.17.5           h35ee89b_0          defaults
libllvm22                    22.1.2           h61cb577_3          defaults
libmamba                     2.3.2            h4b9b42c_3          defaults
libmambapy                   2.3.2            py314h678a34b_3     defaults
libmpdec                     4.0.1            haa24f5a_0          defaults
libnghttp2                   1.69.0           h04a03c9_1          defaults
libsolv                      0.7.39           h01d500d_0          defaults
libssh2                      1.11.1           h3e2b118_0          defaults
libunistring                 1.4.2            hd80fe18_0          defaults
libxml2                      2.15.3           h9e20a13_0          defaults
libzlib                      1.3.2            hb4cf58c_0          defaults
lmdb                         1.0.0            hdceb957_0          defaults
lz4-c                        1.9.4            hd7fd590_5          defaults
markupsafe                   3.0.3            py314haa24f5a_0     defaults
mbedtls                      3.5.1            h313beb8_1          defaults
menuinst                     2.5.2            py314hca03da5_0     defaults
msgpack-python               1.2.1            py314h50f4ffc_0     defaults
ncurses                      6.5              hee39554_0          defaults
nlohmann_json                3.11.2           h313beb8_0          defaults
openssl                      3.5.7            ha0b305a_0          defaults
packaging                    26.0             py314hca03da5_0     defaults
patch                        2.8              h79febb2_0          defaults
pcre2                        10.46            h1dacb4a_0          defaults
pip                          26.1.2           pyh0d26453_0        defaults
pkginfo                      1.12.1.2         py314hca03da5_0     defaults
platformdirs                 4.11.0           py314hca03da5_0     defaults
pluggy                       1.6.0            py314hca03da5_0     defaults
psutil                       7.2.2            py314haa24f5a_0     defaults
py-lief                      0.17.5           py314h35ee89b_0     defaults
py-rattler                   0.25.0           py314h482b559_0     defaults
py-rattler-build             0.65.1           py314h482b559_0     defaults
pybind11-abi                 5                hd3eb1b0_0          defaults
pycosat                      0.6.6            py314h75312c3_2     defaults
pycparser                    3.0              py314hca03da5_0     defaults
pydantic                     2.13.4           py314hca03da5_0     defaults
pydantic-core                2.46.4           py314h3983f12_0     defaults
pyopenssl                    26.3.0           py314hca03da5_0     defaults
pyproject_hooks              1.2.0            py314hca03da5_1     defaults
pysocks                      1.7.1            py314hca03da5_1     defaults
python                       3.14.6           h80e0c04_101_cp314  defaults
python-build                 1.5.1            py314hca03da5_0     defaults
python-installer             1.0.1            py314hca03da5_0     defaults
python-libarchive-c          5.1              pyhd3eb1b0_0        defaults
python.app                   3                py314h75312c3_2     defaults
python_abi                   3.14             4_cp314             defaults
pyyaml                       6.0.3            py314h091b9d3_0     defaults
rattler-build                0.55.1           h02d9002_0          defaults
readline                     8.3              h0b18652_0          defaults
referencing                  0.37.0           py314hca03da5_0     defaults
reproc                       14.2.7           h279499b_0          defaults
reproc-cpp                   14.2.7           h279499b_0          defaults
requests                     2.34.2           py314hca03da5_0     defaults
rpds-py                      0.28.0           py314h931abed_0     defaults
ruamel.yaml                  0.18.16          py314h091b9d3_0     defaults
ruamel.yaml.clib             0.2.14           py314h091b9d3_0     defaults
setuptools                   83.0.0           py314hca03da5_0     defaults
simdjson                     3.10.1           h48ca7d4_0          defaults
soupsieve                    2.8.4            py314hca03da5_0     defaults
sqlite                       3.53.2           h1cce5ff_0          defaults
tapi                         1100.0.11        h8754e6a_1          defaults
tk                           8.6.15           hcd8a7d5_0          defaults
tomli                        2.4.0            py314hca03da5_0     defaults
tomli-w                      1.2.0            pyhd3eb1b0_0        defaults
toolz                        1.1.0            py314hca03da5_0     defaults
tqdm                         4.68.2           py314h7136c26_0     defaults
truststore                   0.10.4           py314hca03da5_0     defaults
typing-extensions            4.16.0           py314hca03da5_0     defaults
typing-inspection            0.4.2            py314hca03da5_0     defaults
typing_extensions            4.16.0           py314hca03da5_0     defaults
tzdata                       2026c            he532380_0          defaults
unearth                      0.18.2           py314hca03da5_0     defaults
urllib3                      2.7.0            py314hca03da5_0     defaults
wheel                        0.47.0           py314hca03da5_0     defaults
xz                           5.8.2            h8bbcb1d_0          defaults
yaml                         0.2.5            h1a28f6b_0          defaults
yaml-cpp                     0.9.0            h9fe17f6_1          defaults
zlib                         1.3.2            hb4cf58c_0          defaults
zstandard                    0.25.0           py314hb3cf4b8_0     defaults
zstd                         1.5.7            h817c040_0          defaults

Additional Context

The package is an arch specific package that is tied to a specific version. I believe it would make sense for the python variant to appear in the content hash. Without this, it can be hard and annoying to know what python version a package was built with.

I think I have traced the behavior which seems ot be caused by this:

# filter out ignored versions
build_string_excludes = ["python", "r_base", "perl", "lua"]
build_string_excludes.extend(
ensure_list(self.config.variant.get("ignore_version", []))
)
if "numpy" in dependencies:
pin_compatible, not_xx = self.uses_numpy_pin_compatible_without_xx
# numpy_xx means it is accounted for in the build string, with npXYY
# if not pin_compatible, then we don't care about the usage, and omit it from the hash.
if self.numpy_xx or (pin_compatible and not not_xx):
build_string_excludes.append("numpy")
# always exclude older stuff that's always in the build string (py, np, pl, r, lua)
if build_string_excludes:
exclude_pattern = re.compile(
"|".join(rf"{exc}[\s$]?.*" for exc in build_string_excludes)
)
dependencies = [
req
for req in dependencies
if not exclude_pattern.match(req) or " " in self.config.variant[req]
]

The reasoning in the comments seems odd IMO:

always exclude older stuff that's always in the build string (py, np, pl, r, lua)

Sure they are in the build string, but why exclude them from the content hash?

Metadata

Metadata

Assignees

No one assigned

    Labels

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

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions